Skip to content

Commit

Permalink
avoid hang when only threads are starting IO
Browse files Browse the repository at this point in the history
When not in threaded region, only thread 0 will manage IO events, but it
may have gone to sleep if there were no IO objects active for it to
watch earlier.

Fix #48430
  • Loading branch information
vtjnash committed Jan 28, 2023
1 parent 87f8958 commit d7693f1
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions src/partr.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,15 @@ JL_DLLEXPORT void jl_wakeup_thread(int16_t tid) JL_NOTSAFEPOINT
}
else {
// something added to the sticky-queue: notify that thread
if (wake_thread(tid)) {
if (wake_thread(tid) && uvlock != ct) {
// check if we need to notify uv_run too
jl_fence();
jl_ptls_t other = jl_atomic_load_relaxed(&jl_all_tls_states)[tid];
jl_task_t *tid_task = jl_atomic_load_relaxed(&other->current_task);
// now that we have changed the thread to not-sleeping, ensure that
// either it has not yet acquired the libuv lock, or that it will
// observe the change of state to not_sleeping
if (uvlock != ct && jl_atomic_load_relaxed(&jl_uv_mutex.owner) == tid_task)
if (jl_atomic_load_relaxed(&jl_uv_mutex.owner) == tid_task)
wake_libuv();
}
}
Expand Down Expand Up @@ -386,7 +386,16 @@ JL_DLLEXPORT jl_task_t *jl_task_get_next(jl_value_t *trypoptask, jl_value_t *q,
}
else if (ptls->tid == 0) {
uvlock = 1;
JL_UV_LOCK(); // jl_mutex_lock(&jl_uv_mutex);
JL_UV_LOCK();
}
else {
// Since we might have started some IO work, we might need
// to ensure tid = 0 will go watch that new event source.
// If trylock would have succeeded, that may have been our
// responsibility, so need to make sure thread 0 will take care
// of us.
if (jl_atomic_load_relaxed(&jl_uv_mutex.owner) == NULL) // aka trylock
jl_wakeup_thread(0);
}
if (uvlock) {
int enter_eventloop = may_sleep(ptls);
Expand Down

0 comments on commit d7693f1

Please sign in to comment.