@@ -901,23 +901,30 @@ handle_weakref_callbacks(PyGC_Head *unreachable, PyGC_Head *old)
901901 for (PyWeakReference * wr = * wrlist ; wr != NULL ; wr = next_wr ) {
902902 next_wr = wr -> wr_next ;
903903
904- // Since Python 2.3, weakrefs to cyclic garbage have been cleared
905- // *before* calling finalizers. However, since tp_subclasses
906- // started being necessary to invalidate caches (e.g. by
907- // PyType_Modified()), that clearing has created a bug. If the
908- // weakref to the subclass is cleared before a finalizer is
909- // called, the cache may not be correctly invalidated. That can
910- // lead to segfaults since the caches can refer to deallocated
904+ // Weakrefs with callbacks always need to be cleared before
905+ // executing the callback. Sometimes the callback will call
906+ // the ref object, to check if it's actually a dead reference
907+ // (KeyedRef does this, for example). We want to indicate that it
908+ // is dead, even though it is possible a finalizer might resurrect
909+ // it. Clearing also prevents the callback from being executing
910+ // more than once.
911+ //
912+ // Since Python 2.3, all weakrefs to cyclic garbage have
913+ // been cleared *before* calling finalizers. However, since
914+ // tp_subclasses started being necessary to invalidate caches
915+ // (e.g. by PyType_Modified()), that clearing has created a bug.
916+ // If the weakref to the subclass is cleared before a finalizer
917+ // is called, the cache may not be correctly invalidated. That
918+ // can lead to segfaults since the caches can refer to deallocated
911919 // objects. Delaying the clear of weakrefs until *after*
912- // finalizers have been called fixes that bug. However, that can
913- // introduce other problems since some finalizer code expects that
914- // the weakrefs will be cleared first. The "multiprocessing"
915- // package contains finalizer logic like this, for example. So,
916- // we have the PyType_Check() test above and only defer the clear
917- // of types. That solves the issue for tp_subclasses. In a
918- // future version of Python, we should likely defer the weakref
919- // clear for all objects, not just types.
920- if (!PyType_Check (wr -> wr_object )) {
920+ // finalizers have been called fixes that bug. However, that
921+ // deferral could introduce other problems if some finalizer
922+ // code expects that the weakrefs will be cleared first. So, we
923+ // have the PyType_Check() test below to only defer the clear of
924+ // weakrefs to types. That solves the issue for tp_subclasses.
925+ // In a future version of Python, we should likely defer the
926+ // weakref clear for all objects, not just types.
927+ if (wr -> wr_callback != NULL || !PyType_Check (wr -> wr_object )) {
921928 // _PyWeakref_ClearRef clears the weakref but leaves the
922929 // callback pointer intact. Obscure: it also changes *wrlist.
923930 _PyObject_ASSERT ((PyObject * )wr , wr -> wr_object == op );
@@ -962,11 +969,6 @@ handle_weakref_callbacks(PyGC_Head *unreachable, PyGC_Head *old)
962969 continue ;
963970 }
964971
965- if (_PyGC_FINALIZED ((PyObject * )wr )) {
966- /* Callback was already run (weakref must have been resurrected). */
967- continue ;
968- }
969-
970972 /* Create a new reference so that wr can't go away
971973 * before we can process it again.
972974 */
@@ -995,10 +997,6 @@ handle_weakref_callbacks(PyGC_Head *unreachable, PyGC_Head *old)
995997 callback = wr -> wr_callback ;
996998 _PyObject_ASSERT (op , callback != NULL );
997999
998- /* Ensure we don't execute the callback again if the weakref is
999- * resurrected. */
1000- _PyGC_SET_FINALIZED (op );
1001-
10021000 /* copy-paste of weakrefobject.c's handle_callback() */
10031001 temp = PyObject_CallOneArg (callback , (PyObject * )wr );
10041002 if (temp == NULL ) {
0 commit comments