@@ -593,13 +593,19 @@ Handle<Value> Statement::Each(const Arguments& args) {
593593 }
594594 else {
595595 baton->completed = Persistent<Function>::New (completed);
596- baton->async = new Async (stmt, baton, AsyncEach);
597596 stmt->Schedule (EIO_BeginEach, baton);
598597 return args.This ();
599598 }
600599}
601600
602601void Statement::EIO_BeginEach (Baton* baton) {
602+ // Only create the Async object when we're actually going into
603+ // the event loop. This prevents dangling events.
604+ EachBaton* each_baton = static_cast <EachBaton*>(baton);
605+ each_baton->async = new Async (each_baton->stmt , AsyncEach);
606+ each_baton->async ->item_cb = Persistent<Function>::New (each_baton->callback );
607+ each_baton->async ->completed_cb = Persistent<Function>::New (each_baton->completed );
608+
603609 STATEMENT_BEGIN (Each);
604610}
605611
@@ -649,6 +655,7 @@ void Statement::EIO_Each(eio_req *req) {
649655
650656void Statement::CloseCallback (uv_handle_t * handle) {
651657 assert (handle != NULL );
658+ assert (handle->data != NULL );
652659 Async* async = static_cast <Async*>(handle->data );
653660 delete async;
654661 handle->data = NULL ;
@@ -657,7 +664,6 @@ void Statement::CloseCallback(uv_handle_t* handle) {
657664void Statement::AsyncEach (uv_async_t * handle, int status) {
658665 HandleScope scope;
659666 Async* async = static_cast <Async*>(handle->data );
660- EachBaton* baton = async->baton ;
661667
662668 while (true ) {
663669 // Get the contents out of the data cache for us to process in the JS callback.
@@ -670,7 +676,7 @@ void Statement::AsyncEach(uv_async_t* handle, int status) {
670676 break ;
671677 }
672678
673- if (!baton-> callback .IsEmpty () && baton-> callback ->IsFunction ()) {
679+ if (!async-> item_cb .IsEmpty () && async-> item_cb ->IsFunction ()) {
674680 Local<Value> argv[2 ];
675681 argv[0 ] = Local<Value>::New (Null ());
676682
@@ -679,20 +685,20 @@ void Statement::AsyncEach(uv_async_t* handle, int status) {
679685 for (int i = 0 ; it < end; it++, i++) {
680686 argv[1 ] = RowToJS (*it);
681687 async->retrieved ++;
682- TRY_CATCH_CALL (async->stmt ->handle_ , baton-> callback , 2 , argv);
688+ TRY_CATCH_CALL (async->stmt ->handle_ , async-> item_cb , 2 , argv);
683689 delete *it;
684690 }
685691 }
686692 }
687693
688694 if (async->completed ) {
689- if (!baton-> completed .IsEmpty () &&
690- baton-> completed ->IsFunction ()) {
695+ if (!async-> completed_cb .IsEmpty () &&
696+ async-> completed_cb ->IsFunction ()) {
691697 Local<Value> argv[] = {
692698 Local<Value>::New (Null ()),
693699 Integer::New (async->retrieved )
694700 };
695- TRY_CATCH_CALL (async->stmt ->handle_ , baton-> completed , 2 , argv);
701+ TRY_CATCH_CALL (async->stmt ->handle_ , async-> completed_cb , 2 , argv);
696702 }
697703 uv_close ((uv_handle_t *)handle, CloseCallback);
698704 }
0 commit comments