[3.14] Revert "GH-91636: Clear weakrefs created by finalizers. (GH-136401) (#141993)" by hugovk · Pull Request #142152 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions Lib/test/test_gc.py

This file was deleted.

25 changes: 3 additions & 22 deletions Python/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ move_legacy_finalizer_reachable(PyGC_Head *finalizers)
* no object in `unreachable` is weakly referenced anymore.
*/
static int
handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old, bool allow_callbacks)
handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
{
PyGC_Head *gc;
PyObject *op; /* generally FROM_GC(gc) */
Expand All @@ -879,9 +879,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old, bool allow_callbacks)
PyGC_Head *next;
int num_freed = 0;

if (allow_callbacks) {
gc_list_init(&wrcb_to_call);
}
gc_list_init(&wrcb_to_call);

/* Clear all weakrefs to the objects in unreachable. If such a weakref
* also has a callback, move it into `wrcb_to_call` if the callback
Expand Down Expand Up @@ -937,11 +935,6 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old, bool allow_callbacks)
_PyObject_ASSERT((PyObject *)wr, wr->wr_object == op);
_PyWeakref_ClearRef(wr);
_PyObject_ASSERT((PyObject *)wr, wr->wr_object == Py_None);

if (!allow_callbacks) {
continue;
}

if (wr->wr_callback == NULL) {
/* no callback */
continue;
Expand Down Expand Up @@ -994,10 +987,6 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old, bool allow_callbacks)
}
}

if (!allow_callbacks) {
return 0;
}

/* Invoke the callbacks we decided to honor. It's safe to invoke them
* because they can't reference unreachable objects.
*/
Expand Down Expand Up @@ -1750,7 +1739,7 @@ gc_collect_region(PyThreadState *tstate,
}

/* Clear weakrefs and invoke callbacks as necessary. */
stats->collected += handle_weakrefs(&unreachable, to, true);
stats->collected += handle_weakrefs(&unreachable, to);
gc_list_validate_space(to, gcstate->visited_space);
validate_list(to, collecting_clear_unreachable_clear);
validate_list(&unreachable, collecting_set_unreachable_clear);
Expand All @@ -1764,14 +1753,6 @@ gc_collect_region(PyThreadState *tstate,
gc_list_init(&final_unreachable);
handle_resurrected_objects(&unreachable, &final_unreachable, to);

/* Clear weakrefs to objects in the unreachable set. No Python-level
* code must be allowed to access those unreachable objects. During
* delete_garbage(), finalizers outside the unreachable set might run
* and create new weakrefs. If those weakrefs were not cleared, they
* could reveal unreachable objects. Callbacks are not executed.
*/
handle_weakrefs(&final_unreachable, NULL, false);

/* Call tp_clear on objects in the final_unreachable set. This will cause
* the reference cycles to be broken. It may also cause some objects
* in finalizers to be freed.
Expand Down
20 changes: 4 additions & 16 deletions Python/gc_free_threading.c
Loading