summaryrefslogtreecommitdiff
path: root/lang/python23/patches/patch-ak
blob: 57c98d35816b5da4349a5cf56425df8ee307e0f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
$NetBSD: patch-ak,v 1.1 2003/12/08 21:13:56 recht Exp $

--- Objects/weakrefobject.c.orig	2003-07-14 23:46:23.000000000 +0200
+++ Objects/weakrefobject.c
@@ -53,17 +53,43 @@ clear_weakref(PyWeakReference *self)
         if (*list == self)
             *list = self->wr_next;
         self->wr_object = Py_None;
-        self->wr_callback = NULL;
         if (self->wr_prev != NULL)
             self->wr_prev->wr_next = self->wr_next;
         if (self->wr_next != NULL)
             self->wr_next->wr_prev = self->wr_prev;
         self->wr_prev = NULL;
         self->wr_next = NULL;
-        Py_XDECREF(callback);
+    }
+    if (callback != NULL) {
+        Py_DECREF(callback);
+        self->wr_callback = NULL;
     }
 }
 
+/* Cyclic gc uses this to *just* clear the passed-in reference, leaving
+ * the callback intact and uncalled.  It must be possible to call self's
+ * tp_dealloc() after calling this, so self has to be left in a sane enough
+ * state for that to work.  We expect tp_dealloc to decref the callback
+ * then.  The reason for not letting clear_weakref() decref the callback
+ * right now is that if the callback goes away, that may in turn trigger
+ * another callback (if a weak reference to the callback exists) -- running
+ * arbitrary Python code in the middle of gc is a disaster.  The convolution
+ * here allows gc to delay triggering such callbacks until the world is in
+ * a sane state again.
+ */
+void
+_PyWeakref_ClearRef(PyWeakReference *self)
+{
+    PyObject *callback;
+
+    assert(self != NULL);
+    assert(PyWeakref_Check(self));
+    /* Preserve and restore the callback around clear_weakref. */
+    callback = self->wr_callback;
+    self->wr_callback = NULL;
+    clear_weakref(self);
+    self->wr_callback = callback;
+}
 
 static void
 weakref_dealloc(PyWeakReference *self)
@@ -117,7 +143,7 @@ weakref_hash(PyWeakReference *self)
     self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self));
     return self->hash;
 }
-    
+
 
 static PyObject *
 weakref_repr(PyWeakReference *self)
@@ -324,7 +350,7 @@ WRAP_BINARY(proxy_iand, PyNumber_InPlace
 WRAP_BINARY(proxy_ixor, PyNumber_InPlaceXor)
 WRAP_BINARY(proxy_ior, PyNumber_InPlaceOr)
 
-static int 
+static int
 proxy_nonzero(PyWeakReference *proxy)
 {
     PyObject *o = PyWeakref_GET_OBJECT(proxy);