@@ -134,6 +134,7 @@ void jl_wake_signal_watchers(void)
134134}
135135
136136jl_mutex_t jl_uv_mutex ;
137+ int jl_uv_loop_unwatched = 0 ;
137138
138139void jl_init_uv (void )
139140{
@@ -170,6 +171,12 @@ JL_DLLEXPORT void jl_iolock_begin(void) JL_CANSAFEPOINT
170171 */
171172JL_DLLEXPORT void jl_iolock_end (void ) JL_CANSAFEPOINT
172173{
174+ // if we leave work in the loop while nobody runs it, wake the event loop thread
175+ // (before unlocking, which can throw)
176+ if (jl_uv_mutex .count == 1 && jl_uv_loop_unwatched && uv_loop_alive (jl_io_loop )) {
177+ jl_uv_loop_unwatched = 0 ;
178+ jl_wake_io_loop_thread ();
179+ }
173180 JL_UV_UNLOCK ();
174181}
175182
@@ -432,7 +439,7 @@ static void jl_proc_exit_cleanup_cb(uv_process_t *process, int64_t exit_status,
432439 */
433440JL_DLLEXPORT void jl_close_uv (uv_handle_t * handle )
434441{
435- JL_UV_LOCK ();
442+ jl_iolock_begin ();
436443 if (handle -> type == UV_PROCESS && ((uv_process_t * )handle )-> pid != 0 ) {
437444 // take ownership of this handle,
438445 // so we can waitpid for the resource to exit and avoid leaving zombies
@@ -460,7 +467,7 @@ JL_DLLEXPORT void jl_close_uv(uv_handle_t *handle)
460467 uv_close (handle , & jl_uv_closeHandle );
461468 }
462469 }
463- JL_UV_UNLOCK ();
470+ jl_iolock_end ();
464471}
465472
466473/**
@@ -471,11 +478,11 @@ JL_DLLEXPORT void jl_close_uv(uv_handle_t *handle)
471478JL_DLLEXPORT void jl_forceclose_uv (uv_handle_t * handle ) JL_CANSAFEPOINT
472479{
473480 if (!uv_is_closing (handle )) { // avoid double-closing the stream
474- JL_UV_LOCK ();
481+ jl_iolock_begin ();
475482 if (!uv_is_closing (handle )) { // double-check
476483 uv_close (handle , & jl_uv_closeHandle );
477484 }
478- JL_UV_UNLOCK ();
485+ jl_iolock_end ();
479486 }
480487}
481488
@@ -556,9 +563,9 @@ JL_DLLEXPORT int jl_spawn(char *name, char **argv,
556563 }
557564 }
558565 opts .exit_cb = cb ;
559- JL_UV_LOCK ();
566+ jl_iolock_begin ();
560567 int r = uv_spawn (loop , proc , & opts );
561- JL_UV_UNLOCK ();
568+ jl_iolock_end ();
562569 return r ;
563570}
564571
@@ -707,10 +714,10 @@ JL_DLLEXPORT int jl_uv_write(uv_stream_t *stream, const char *data, size_t n,
707714 uv_buf_t buf [1 ];
708715 buf [0 ].base = (char * )data ;
709716 buf [0 ].len = n ;
710- JL_UV_LOCK ();
717+ jl_iolock_begin ();
711718 JL_SIGATOMIC_BEGIN ();
712719 int err = uv_write (uvw , stream , buf , 1 , writecb );
713- JL_UV_UNLOCK ();
720+ jl_iolock_end ();
714721 JL_SIGATOMIC_END ();
715722 return err ;
716723}
@@ -775,10 +782,10 @@ JL_DLLEXPORT void jl_uv_puts(uv_stream_t *stream, const char *str, size_t n)
775782 buf [0 ].base = data ;
776783 buf [0 ].len = n ;
777784 req -> data = NULL ;
778- JL_UV_LOCK ();
785+ jl_iolock_begin ();
779786 JL_SIGATOMIC_BEGIN ();
780787 int status = uv_write (req , stream , buf , 1 , (uv_write_cb )jl_uv_writecb );
781- JL_UV_UNLOCK ();
788+ jl_iolock_end ();
782789 JL_SIGATOMIC_END ();
783790 if (status < 0 ) {
784791 jl_uv_writecb (req , status );
@@ -1261,9 +1268,9 @@ JL_DLLEXPORT int jl_queue_work(work_cb_t work_func, void *work_ctx,
12611268 baton -> notify_data1 = notify_data1 ;
12621269 baton -> notify_data2 = notify_data2 ;
12631270
1264- JL_UV_LOCK ();
1271+ jl_iolock_begin ();
12651272 uv_queue_work (jl_io_loop , & baton -> req , jl_work_wrapper , jl_work_notifier );
1266- JL_UV_UNLOCK ();
1273+ jl_iolock_end ();
12671274
12681275 return 0 ;
12691276}
0 commit comments