Skip to content

Commit

Permalink
Wake up libuv main loop on SIGINT
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed May 5, 2016
1 parent 7664f20 commit 246654c
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ void _julia_init(JL_IMAGE_SEARCH rel)
ios_set_io_wait_func = jl_set_io_wait;
jl_io_loop = uv_default_loop(); // this loop will internal events (spawning process etc.),
// best to call this first, since it also initializes libuv
jl_init_signal_async();
restore_signals();
jl_resolve_sysimg_location(rel);
// loads sysimg if available, and conditionally sets jl_options.cpu_target
Expand Down
25 changes: 25 additions & 0 deletions src/jl_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@
extern "C" {
#endif

static uv_async_t signal_async;

static void jl_signal_async_cb(uv_async_t *hdl)
{
// This should abort the current loop and the julia code it returns to
// or the safepoint in the callers of `uv_run` should throw the exception.
(void)hdl;
uv_stop(jl_io_loop);
}

void jl_wake_libuv(void)
{
uv_async_send(&signal_async);
}

void jl_init_signal_async(void)
{
uv_async_init(jl_io_loop, &signal_async, jl_signal_async_cb);
}

extern jl_module_t *jl_old_base_module;
static jl_value_t *close_cb = NULL;

Expand Down Expand Up @@ -80,6 +100,8 @@ JL_DLLEXPORT void jl_uv_closeHandle(uv_handle_t *handle)
// also let the client app do its own cleanup
if (handle->type != UV_FILE && handle->data)
jl_uv_call_close_callback((jl_value_t*)handle->data);
if (handle == (uv_handle_t*)&signal_async)
return;
free(handle);
}

Expand Down Expand Up @@ -114,6 +136,7 @@ JL_DLLEXPORT int jl_run_once(uv_loop_t *loop)
{
if (loop) {
loop->stop_flag = 0;
jl_gc_safepoint();
return uv_run(loop,UV_RUN_ONCE);
}
else return 0;
Expand All @@ -123,6 +146,7 @@ JL_DLLEXPORT void jl_run_event_loop(uv_loop_t *loop)
{
if (loop) {
loop->stop_flag = 0;
jl_gc_safepoint();
uv_run(loop,UV_RUN_DEFAULT);
}
}
Expand All @@ -131,6 +155,7 @@ JL_DLLEXPORT int jl_process_events(uv_loop_t *loop)
{
if (loop) {
loop->stop_flag = 0;
jl_gc_safepoint();
return uv_run(loop,UV_RUN_NOWAIT);
}
else return 0;
Expand Down
2 changes: 2 additions & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ void jl_init_root_task(void *stack, size_t ssize);
void jl_init_serializer(void);
void jl_gc_init(void);
void jl_init_restored_modules(jl_array_t *init_order);
void jl_init_signal_async(void);

void _julia_init(JL_IMAGE_SEARCH rel);
#ifdef COPY_STACKS
Expand Down Expand Up @@ -309,6 +310,7 @@ void jl_safepoint_defer_sigint(void);
// Return `1` if the sigint should be delivered and `0` if there's no sigint
// to be delivered.
int jl_safepoint_consume_sigint(void);
void jl_wake_libuv(void);

#ifdef JULIA_ENABLE_THREADING
jl_get_ptls_states_func jl_get_ptls_states_getter(void);
Expand Down
3 changes: 3 additions & 0 deletions src/signals-mach.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ static void jl_try_deliver_sigint(void)
jl_clear_force_sigint();
jl_throw_in_thread(0, thread, jl_interrupt_exception);
}
else {
jl_wake_libuv();
}

ret = thread_resume(thread);
HANDLE_MACH_ERROR("thread_resume", ret);
Expand Down
1 change: 1 addition & 0 deletions src/signals-unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static void jl_try_deliver_sigint(void)
{
jl_tls_states_t *ptls = jl_all_task_states[0].ptls;
jl_safepoint_enable_sigint();
jl_wake_libuv();
jl_atomic_store_release(&ptls->signal_request, 2);
// This also makes sure `sleep` is aborted.
pthread_kill(jl_all_task_states[0].system_id, SIGUSR2);
Expand Down
2 changes: 2 additions & 0 deletions src/signals-win.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static void jl_try_throw_sigint(void)
{
jl_tls_states_t *ptls = jl_get_ptls_states();
jl_safepoint_enable_sigint();
jl_wake_libuv();
int force = jl_check_force_sigint();
if (force || (!ptls->defer_signal && ptls->io_wait)) {
jl_safepoint_consume_sigint();
Expand Down Expand Up @@ -127,6 +128,7 @@ static void jl_try_deliver_sigint(void)
{
jl_tls_states_t *ptls = jl_all_task_states[0].ptls;
jl_safepoint_enable_sigint();
jl_wake_libuv();
if ((DWORD)-1 == SuspendThread(hMainThread)) {
// error
jl_safe_printf("error: SuspendThread failed\n");
Expand Down

0 comments on commit 246654c

Please sign in to comment.