summaryrefslogtreecommitdiff
path: root/Objects/weakrefobject.c
diff options
context:
space:
mode:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-06-16 19:50:09 +0000
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-06-16 19:50:09 +0000
commitc856c7a2f05f059a7f53dc2238f1e271cb1caaa1 (patch)
treeaf2e221d61d2a1e5c49f444c68bac46d34862bb9 /Objects/weakrefobject.c
parent27d63678a31f1adcf5f2f0f9f88d6b78e93a9c52 (diff)
downloadcpython-git-c856c7a2f05f059a7f53dc2238f1e271cb1caaa1.tar.gz
Merged revisions 64309 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r64309 | amaury.forgeotdarc | 2008-06-16 21:12:42 +0200 (lun., 16 juin 2008) | 8 lines 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/weakrefobject.c')
-rw-r--r--Objects/weakrefobject.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 040e93810d..302cdc9edf 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -884,7 +884,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);
}
}
@@ -902,9 +903,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;
@@ -912,6 +919,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);