summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-06-16 19:12:42 (GMT)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-06-16 19:12:42 (GMT)
commita8919fe631c50a35d355e7174676283ca57e465e (patch)
tree2275d64a09c5b95c92ff04ca21777a983623823f /Objects
parent305480c9dcec736cba91db62062f75b5ceff9b60 (diff)
downloadcpython-a8919fe631c50a35d355e7174676283ca57e465e.zip
cpython-a8919fe631c50a35d355e7174676283ca57e465e.tar.gz
cpython-a8919fe631c50a35d355e7174676283ca57e465e.tar.bz2
Issue 3110: Crash with weakref subclass,
seen after a "import multiprocessing.reduction" An instance of a weakref subclass can have attributes. If such a weakref holds the only strong reference to the object, deleting the weakref will delete the object. In this case, the callback must not be called, because the ref object is being deleted!
Diffstat (limited to 'Objects')
-rw-r--r--Objects/weakrefobject.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 1aee5a5..5cd9173 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -907,7 +907,8 @@ PyObject_ClearWeakRefs(PyObject *object)
current->wr_callback = NULL;
clear_weakref(current);
if (callback != NULL) {
- handle_callback(current, callback);
+ if (current->ob_refcnt > 0)
+ handle_callback(current, callback);
Py_DECREF(callback);
}
}
@@ -925,9 +926,15 @@ PyObject_ClearWeakRefs(PyObject *object)
for (i = 0; i < count; ++i) {
PyWeakReference *next = current->wr_next;
- Py_INCREF(current);
- PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
- PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
+ if (current->ob_refcnt > 0)
+ {
+ Py_INCREF(current);
+ PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
+ PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
+ }
+ else {
+ Py_DECREF(current->wr_callback);
+ }
current->wr_callback = NULL;
clear_weakref(current);
current = next;
@@ -935,6 +942,7 @@ PyObject_ClearWeakRefs(PyObject *object)
for (i = 0; i < count; ++i) {
PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
+ /* The tuple may have slots left to NULL */
if (callback != NULL) {
PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
handle_callback((PyWeakReference *)item, callback);