Skip to content

Commit 100e305

Browse files
authored
prevent deadlock when releasing the jl_unique_gcsafe_lock causes gc (#56563)
Caught this by running threads test repeatedly locally: the sweep needs to acquire engine_lock, so we need to make sure to release that first (the other jl_unique_gcsafe_lock users shouldn't care about this ordering since they don't acquire their locks during sweeping)
1 parent d99d569 commit 100e305

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

src/julia_locks.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,16 @@ class jl_unique_gcsafe_lock {
115115
explicit jl_unique_gcsafe_lock(std::mutex &native) JL_NOTSAFEPOINT_ENTER
116116
{
117117
jl_task_t *ct = jl_current_task;
118-
gc_state = jl_gc_safe_enter(ct->ptls);
118+
gc_state = jl_gc_safe_enter(ct->ptls); // contains jl_gc_safepoint after enter
119119
this->native = std::unique_lock(native);
120120
ct->ptls->engine_nqueued++; // disables finalizers until inference is finished on this method graph
121121
}
122122
jl_unique_gcsafe_lock(jl_unique_gcsafe_lock &&native) = delete;
123123
jl_unique_gcsafe_lock(jl_unique_gcsafe_lock &native) = delete;
124124
~jl_unique_gcsafe_lock() JL_NOTSAFEPOINT_LEAVE {
125125
jl_task_t *ct = jl_current_task;
126-
jl_gc_safe_leave(ct->ptls, gc_state);
126+
native.unlock();
127+
jl_gc_safe_leave(ct->ptls, gc_state); // contains jl_gc_safepoint after leave
127128
ct->ptls->engine_nqueued--; // enable finalizers (but don't run them until the next gc)
128129
}
129130
void wait(std::condition_variable& cond) JL_NOTSAFEPOINT {

0 commit comments

Comments
 (0)