Skip to content

Commit 12f0b5c

Browse files
committed
Run clear_weakrefs() with world stopped.
1 parent 17a4f9e commit 12f0b5c

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

Python/gc_free_threading.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,11 +2255,28 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
22552255
call_weakref_callbacks(state);
22562256
finalize_garbage(state);
22572257

2258-
// Handle any objects that may have resurrected after the finalization.
22592258
_PyEval_StopTheWorld(interp);
2259+
// Handle any objects that may have resurrected after the finalization.
22602260
err = handle_resurrected_objects(state);
22612261
// Clear free lists in all threads
22622262
_PyGC_ClearAllFreeLists(interp);
2263+
if (err == 0) {
2264+
// Clear weakrefs to objects in the unreachable set. No Python-level
2265+
// code must be allowed to access those unreachable objects. During
2266+
// delete_garbage(), finalizers outside the unreachable set might
2267+
// run and if those weakrefs were not cleared, that could reveal
2268+
// unreachable objects.
2269+
//
2270+
// We used to clear weakrefs earlier, before calling finalizers.
2271+
// That causes at least two problems. First, the finalizers could
2272+
// create new weakrefs, that refer to unreachable objects. Those
2273+
// would not be cleared and could cause the problem described above
2274+
// (see GH-91636 as an example). Second, we need the weakrefs in the
2275+
// tp_subclasses to *not* be cleared so that caches based on the type
2276+
// version are correctly invalidated (see GH-135552 as a bug caused by
2277+
// this).
2278+
clear_weakrefs(state);
2279+
}
22632280
_PyEval_StartTheWorld(interp);
22642281

22652282
if (err < 0) {
@@ -2271,21 +2288,6 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
22712288
return;
22722289
}
22732290

2274-
// Clear weakrefs to objects in the unreachable set. No Python-level
2275-
// code must be allowed to access those unreachable objects. During
2276-
// delete_garbage(), finalizers outside the unreachable set might run
2277-
// and if those weakrefs were not cleared, that could reveal unreachable
2278-
// objects.
2279-
//
2280-
// We used to clear weakrefs earlier, before calling finalizers. That
2281-
// causes at least two problems. First, the finalizers could create
2282-
// new weakrefs, that refer to unreachable objects. Those would not be
2283-
// cleared and could cause the problem described above (see GH-91636 as
2284-
// an example). Second, we need the weakrefs in the tp_subclasses to
2285-
// *not* be cleared so that caches based on the type version are correctly
2286-
// invalidated (see GH-135552 as a bug caused by this).
2287-
clear_weakrefs(state);
2288-
22892291
// Call tp_clear on objects in the unreachable set. This will cause
22902292
// the reference cycles to be broken. It may also cause some objects
22912293
// to be freed.

0 commit comments

Comments
 (0)