Skip to content

Commit c54a3f2

Browse files
authored
allow finalizers to take any locks and yield during exit (#51848)
This aligns their behavior with manual calls to `finalize(o)`, and prepares for a future time in which these functions are always run on a separate thread. This means that they can wait to acquire locks in this context, which otherwise would have been denied to them.
1 parent 3493473 commit c54a3f2

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

src/gc.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ JL_DLLEXPORT void jl_gc_init_finalizer_rng_state(void)
425425
jl_rng_split(finalizer_rngState, jl_current_task->rngState);
426426
}
427427

428-
static void run_finalizers(jl_task_t *ct)
428+
static void run_finalizers(jl_task_t *ct, int finalizers_thread)
429429
{
430430
// Racy fast path:
431431
// The race here should be OK since the race can only happen if
@@ -453,7 +453,7 @@ static void run_finalizers(jl_task_t *ct)
453453

454454
// This releases the finalizers lock.
455455
int8_t was_in_finalizer = ct->ptls->in_finalizer;
456-
ct->ptls->in_finalizer = 1;
456+
ct->ptls->in_finalizer = !finalizers_thread;
457457
jl_gc_run_finalizers_in_list(ct, &copied_list);
458458
ct->ptls->in_finalizer = was_in_finalizer;
459459
arraylist_free(&copied_list);
@@ -467,7 +467,7 @@ JL_DLLEXPORT void jl_gc_run_pending_finalizers(jl_task_t *ct)
467467
ct = jl_current_task;
468468
jl_ptls_t ptls = ct->ptls;
469469
if (!ptls->in_finalizer && ptls->locks.len == 0 && ptls->finalizers_inhibited == 0) {
470-
run_finalizers(ct);
470+
run_finalizers(ct, 0);
471471
}
472472
}
473473

@@ -560,7 +560,7 @@ void jl_gc_run_all_finalizers(jl_task_t *ct)
560560
JL_UNLOCK_NOGC(&finalizers_lock);
561561
gc_n_threads = 0;
562562
gc_all_tls_states = NULL;
563-
run_finalizers(ct);
563+
run_finalizers(ct, 1);
564564
}
565565

566566
void jl_gc_add_finalizer_(jl_ptls_t ptls, void *v, void *f) JL_NOTSAFEPOINT
@@ -3588,7 +3588,7 @@ JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection)
35883588
// or wait for finalizers on other threads without dead lock).
35893589
if (!ptls->finalizers_inhibited && ptls->locks.len == 0) {
35903590
JL_TIMING(GC, GC_Finalizers);
3591-
run_finalizers(ct);
3591+
run_finalizers(ct, 0);
35923592
}
35933593
JL_PROBE_GC_FINALIZER();
35943594

0 commit comments

Comments
 (0)