]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
one more for the night.
authorAnthony Baxter <anthonybaxter@gmail.com>
Thu, 1 Nov 2001 15:34:20 +0000 (15:34 +0000)
committerAnthony Baxter <anthonybaxter@gmail.com>
Thu, 1 Nov 2001 15:34:20 +0000 (15:34 +0000)
backport of 2.26:
  Make the gc.collect() function respect the collection lock.  This fixes
  SF bug 476129: "gc.collect sometimes hangs".

Modules/gcmodule.c

index a879ef6c2d0f9a153536958152ec5a574cb56a7d..e781bdf9e7869d90b0225f7a727756fba0db0143 100644 (file)
@@ -43,6 +43,9 @@ static int threshold2 = 10;  /* generation1 collections before collecting 2 */
 /* net new objects allocated since last collection */
 static int allocated;
 
+/* true if we are currently running the collector */
+static int collecting;
+
 /* set for debugging information */
 #define DEBUG_STATS            (1<<0) /* print collection statistics */
 #define DEBUG_COLLECTABLE      (1<<1) /* print collectable objects */
@@ -490,8 +493,6 @@ collect_generations(void)
 void
 _PyGC_Insert(PyObject *op)
 {
-       /* collection lock since collecting may cause allocations */
-       static int collecting = 0;
 
 #ifdef Py_DEBUG
        if (!PyObject_IS_GC(op)) {
@@ -503,9 +504,9 @@ _PyGC_Insert(PyObject *op)
            threshold0 &&
            !collecting &&
            !PyErr_Occurred()) {
-               collecting++;
+               collecting = 1;
                collect_generations();
-               collecting--;
+               collecting = 0;
        }
        allocated++;
        gc_list_append(PyObject_AS_GC(op), &generation0);
@@ -594,10 +595,17 @@ gc_collect(PyObject *self, PyObject *args)
        if (!PyArg_ParseTuple(args, ":collect"))        /* check no args */
                return NULL;
 
-       generation = 2;
-       gc_list_merge(&generation0, &generation2);
-       gc_list_merge(&generation1, &generation2);
-       n = collect(&generation2, &generation2);
+       if (collecting) {
+               n = 0; /* already collecting, don't do anything */
+       }
+       else {
+               collecting = 1;
+               generation = 2;
+               gc_list_merge(&generation0, &generation2);
+               gc_list_merge(&generation1, &generation2);
+               n = collect(&generation2, &generation2);
+               collecting = 0;
+       }
 
        return Py_BuildValue("l", n);
 }