diff options
| author | Charalampos Stratakis <cstratak@redhat.com> | 2016-10-14 16:37:19 +0200 |
|---|---|---|
| committer | Tim Orling <timothy.t.orling@linux.intel.com> | 2016-10-14 10:43:32 -0700 |
| commit | b6cf0f4b31e461054b1fdbb8ae66c172cb188625 (patch) | |
| tree | 750640d4491733e4aeb109aa328b7dc6f9767f1a /00248-ensure-gc-tracking-is-off-when-invoking-weakref-callbacks.patch | |
| parent | 95fa805be59258acc4a3a9330296719b238f79ee (diff) | |
| download | python34-el6.tar.gz python34-el6.tar.xz python34-el6.zip | |
Ensure gc tracking is off when invoking weakref callbacksel6
- also correct typos in prior changelog
Diffstat (limited to '00248-ensure-gc-tracking-is-off-when-invoking-weakref-callbacks.patch')
| -rw-r--r-- | 00248-ensure-gc-tracking-is-off-when-invoking-weakref-callbacks.patch | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/00248-ensure-gc-tracking-is-off-when-invoking-weakref-callbacks.patch b/00248-ensure-gc-tracking-is-off-when-invoking-weakref-callbacks.patch new file mode 100644 index 0000000..330a6e3 --- /dev/null +++ b/00248-ensure-gc-tracking-is-off-when-invoking-weakref-callbacks.patch @@ -0,0 +1,87 @@ + +# HG changeset patch +# User Benjamin Peterson <benjamin@python.org> +# Date 1475564402 25200 +# Node ID c9b7272e25532f84d7feb1b0d942978329156ace +# Parent b24d0f274623d100e9bad7a4cb1b3f1a3e0b82b1 +ensure gc tracking is off when invoking weakref callbacks (closes #26617) + +diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py +--- a/Lib/test/test_weakref.py ++++ b/Lib/test/test_weakref.py +@@ -845,6 +845,14 @@ class ReferencesTestCase(TestBase): + with self.assertRaises(AttributeError): + ref1.__callback__ = lambda ref: None + ++ def test_callback_gcs(self): ++ class ObjectWithDel(Object): ++ def __del__(self): pass ++ x = ObjectWithDel(1) ++ ref1 = weakref.ref(x, lambda ref: support.gc_collect()) ++ del x ++ support.gc_collect() ++ + + class SubclassableWeakrefTestCase(TestBase): + +diff --git a/Objects/typeobject.c b/Objects/typeobject.c +--- a/Objects/typeobject.c ++++ b/Objects/typeobject.c +@@ -1123,11 +1123,6 @@ subtype_dealloc(PyObject *self) + Py_TRASHCAN_SAFE_BEGIN(self); + --_PyTrash_delete_nesting; + -- tstate->trash_delete_nesting; +- /* DO NOT restore GC tracking at this point. weakref callbacks +- * (if any, and whether directly here or indirectly in something we +- * call) may trigger GC, and if self is tracked at that point, it +- * will look like trash to GC and GC will try to delete self again. +- */ + + /* Find the nearest base with a different tp_dealloc */ + base = type; +@@ -1138,30 +1133,36 @@ subtype_dealloc(PyObject *self) + + has_finalizer = type->tp_finalize || type->tp_del; + +- /* Maybe call finalizer; exit early if resurrected */ +- if (has_finalizer) ++ if (type->tp_finalize) { + _PyObject_GC_TRACK(self); +- +- if (type->tp_finalize) { + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + /* Resurrected */ + goto endlabel; + } +- } +- /* If we added a weaklist, we clear it. Do this *before* calling +- tp_del, clearing slots, or clearing the instance dict. */ ++ _PyObject_GC_UNTRACK(self); ++ } ++ /* ++ If we added a weaklist, we clear it. Do this *before* calling tp_del, ++ clearing slots, or clearing the instance dict. ++ ++ GC tracking must be off at this point. weakref callbacks (if any, and ++ whether directly here or indirectly in something we call) may trigger GC, ++ and if self is tracked at that point, it will look like trash to GC and GC ++ will try to delete self again. ++ */ + if (type->tp_weaklistoffset && !base->tp_weaklistoffset) + PyObject_ClearWeakRefs(self); + + if (type->tp_del) { ++ _PyObject_GC_TRACK(self); + type->tp_del(self); + if (self->ob_refcnt > 0) { + /* Resurrected */ + goto endlabel; + } ++ _PyObject_GC_UNTRACK(self); + } + if (has_finalizer) { +- _PyObject_GC_UNTRACK(self); + /* New weakrefs could be created during the finalizer call. + If this occurs, clear them out without calling their + finalizers since they might rely on part of the object + |
