Index: Modules/gcmodule.c =================================================================== --- Modules/gcmodule.c (revision 86684) +++ Modules/gcmodule.c (working copy) @@ -68,6 +68,9 @@ /* Python string used to look for __del__ attribute. */ static PyObject *delstr = NULL; +/* a callback to be invoked when collection is done */ +static PyObject *callback = NULL; + /* This is the number of objects who survived the last full collection. It approximates the number of long lived objects tracked by the GC. @@ -111,7 +114,7 @@ thusly: "each full garbage collection is more and more costly as the number of objects grows, but we do fewer and fewer of them"). - This heuristic was suggested by Martin von Löwis on python-dev in + This heuristic was suggested by Martin von Löwis on python-dev in June 2008. His original analysis and proposal can be found at: http://mail.python.org/pipermail/python-dev/2008-June/080579.html */ @@ -948,6 +951,13 @@ int i; Py_ssize_t n = 0; + /* Invoke callback */ + if (callback) { + PyObject *r = PyObject_CallFunction(callback, "l", 1); + Py_XDECREF(r); + PyErr_Clear(); + } + /* Find the oldest generation (highest numbered) where the count * exceeds the threshold. Objects in the that generation and * generations younger than it will be collected. */ @@ -964,6 +974,14 @@ break; } } + + /* Invoke callback */ + if (callback) { + PyObject *r = PyObject_CallFunction(callback, "ll", 0, n); + Py_XDECREF(r); + PyErr_Clear(); + } + return n; } @@ -1256,6 +1274,33 @@ } +static PyObject * +gc_get_callback(PyObject *self, PyObject *noargs) +{ + PyObject *cb = callback; + if (!cb) + cb = Py_None; + Py_INCREF(cb); + return cb; +} + + +static PyObject * +gc_set_callback(PyObject *self, PyObject *args) +{ + PyObject *cb; + if (!PyArg_ParseTuple(args, "O:set_callback", &cb)) + return 0; + if (cb == Py_None) + cb = 0; + Py_XINCREF(cb); + Py_XDECREF(callback); + callback = cb; + Py_INCREF(Py_None); + return Py_None; +} + + PyDoc_STRVAR(gc__doc__, "This module provides access to the garbage collector for reference cycles.\n" "\n" @@ -1290,6 +1335,8 @@ gc_get_referrers__doc__}, {"get_referents", gc_get_referents, METH_VARARGS, gc_get_referents__doc__}, + {"get_callback", gc_get_callback, METH_NOARGS, ""}, + {"set_callback", gc_set_callback, METH_VARARGS, ""}, {NULL, NULL} /* Sentinel */ };