]> granicus.if.org Git - python/commitdiff
This is Neil's fix for SF bug 535905 (Evil Trashcan and GC interaction).
authorGuido van Rossum <guido@python.org>
Thu, 28 Mar 2002 20:34:59 +0000 (20:34 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 28 Mar 2002 20:34:59 +0000 (20:34 +0000)
The fix makes it possible to call PyObject_GC_UnTrack() more than once
on the same object, and then move the PyObject_GC_UnTrack() call to
*before* the trashcan code is invoked.

BUGFIX CANDIDATE!

Modules/gcmodule.c
Objects/dictobject.c
Objects/frameobject.c
Objects/listobject.c
Objects/tupleobject.c

index 71e9596e4b93a285a415ca00992c7fd78e64fd24..ed25bd4fec8934a745cbe08a4c1db1cb48a8de2c 100644 (file)
@@ -819,7 +819,9 @@ _PyObject_GC_Track(PyObject *op)
 void
 _PyObject_GC_UnTrack(PyObject *op)
 {
-       _PyObject_GC_UNTRACK(op);
+       PyGC_Head *gc = AS_GC(op);
+       if (gc->gc.gc_next != NULL)
+               _PyObject_GC_UNTRACK(op);
 }
 
 PyObject *
index 5803c574061a24020492ba0183e6780874c05e6c..a83a8512f3c7798141e890bc9e458e760a1ba482 100644 (file)
@@ -694,8 +694,8 @@ dict_dealloc(register dictobject *mp)
 {
        register dictentry *ep;
        int fill = mp->ma_fill;
+       PyObject_GC_UnTrack(mp);
        Py_TRASHCAN_SAFE_BEGIN(mp)
-       _PyObject_GC_UNTRACK(mp);
        for (ep = mp->ma_table; fill > 0; ep++) {
                if (ep->me_key) {
                        --fill;
index cf3d73ac929481c03a52d2089ff186b8c2bac58a..8e4c60ff2722a2af20498998122e8c981544b71e 100644 (file)
@@ -67,8 +67,8 @@ frame_dealloc(PyFrameObject *f)
        PyObject **fastlocals;
        PyObject **p;
 
+       PyObject_GC_UnTrack(f);
        Py_TRASHCAN_SAFE_BEGIN(f)
-       _PyObject_GC_UNTRACK(f);
        /* Kill all local variables */
        slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
        fastlocals = f->f_localsplus;
index dbbc4a99587a67ab1b7c105130e5e37a65385221..f3821f86fac03cecf3c25a9516c4509f4ac55861 100644 (file)
@@ -195,8 +195,8 @@ static void
 list_dealloc(PyListObject *op)
 {
        int i;
+       PyObject_GC_UnTrack(op);
        Py_TRASHCAN_SAFE_BEGIN(op)
-       _PyObject_GC_UNTRACK(op);
        if (op->ob_item != NULL) {
                /* Do it backwards, for Christian Tismer.
                   There's a simple test case where somehow this reduces
index 27598ed6fe0559de240e490fd747347f15d2ad28..ab792def9323a31a9d8388831dda6cf07ad422fe 100644 (file)
@@ -139,8 +139,8 @@ tupledealloc(register PyTupleObject *op)
 {
        register int i;
        register int len =  op->ob_size;
+       PyObject_GC_UnTrack(op);
        Py_TRASHCAN_SAFE_BEGIN(op)
-       _PyObject_GC_UNTRACK(op);
        if (len > 0) {
                i = len;
                while (--i >= 0)