Index: subversion/bindings/swig/core.i =================================================================== --- subversion/bindings/swig/core.i (revision 16784) +++ subversion/bindings/swig/core.i (working copy) @@ -632,7 +632,6 @@ void svn_swig_py_set_application_pool(PyObject *py_pool, apr_pool_t *pool); void svn_swig_py_clear_application_pool(); -PyObject *svn_swig_py_register_cleanup(PyObject *py_pool, apr_pool_t *pool); %init %{ /* Theoretically, we should be checking for errors here, Index: subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c =================================================================== --- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (revision 16784) +++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (working copy) @@ -136,50 +136,6 @@ _global_svn_swig_py_pool = NULL; } -/* Mark a pool as deleted after it is destroyed */ -static apr_status_t svn_swig_py_pool_destroyed(void *ptr) -{ - PyObject *pool = (PyObject *) ptr; - svn_swig_py_acquire_py_lock(); - PyObject_DelAttrString(pool, isValid); - svn_swig_py_release_py_lock(); - return APR_SUCCESS; -} - -/* Decrease a pool's reference count after it is destroyed */ -static apr_status_t svn_swig_py_pool_decref(void *ptr) -{ - PyObject *pool = (PyObject *) ptr; - svn_swig_py_acquire_py_lock(); - Py_DECREF(pool); - svn_swig_py_release_py_lock(); - return APR_SUCCESS; -} - -/* Register cleanup function */ -PyObject * svn_swig_py_register_cleanup(PyObject *py_pool, apr_pool_t *pool) -{ - PyObject *result; - - svn_swig_py_acquire_py_lock(); - - /* Check that the pool object is valid */ - result = PyObject_CallMethod(py_pool, assertValid, emptyTuple); - if (result == NULL) { - return NULL; - } - Py_DECREF(result); - svn_swig_py_release_py_lock(); - - /* Delete the "_isvalid" member when the pool is destroyed */ - apr_pool_cleanup_register(pool, py_pool, svn_swig_py_pool_destroyed, - apr_pool_cleanup_null); - - /* Return None */ - Py_INCREF(Py_None); - return Py_None; -} - /* Get the application pool */ void svn_swig_get_application_pool(PyObject **py_pool, apr_pool_t **pool) { @@ -202,7 +158,11 @@ Py_DECREF(result); } } else { + printf("pool %d %d\n", pool, PyObject_HasAttrString(pool, wrap)); result = PyObject_CallMethod(pool, wrap, objectTuple, *proxy); + if (result == NULL) { + return 1; + } Py_DECREF(*proxy); *proxy = result; } @@ -380,9 +340,6 @@ return NULL; } - apr_pool_cleanup_register((apr_pool_t *)pool, py_pool, - svn_swig_py_pool_decref, apr_pool_cleanup_null); - if (proxy_set_pool(&py_pool, NULL)) { Py_DECREF(py_pool); return NULL; Index: subversion/bindings/swig/include/proxy_apr.swg =================================================================== --- subversion/bindings/swig/include/proxy_apr.swg (revision 16784) +++ subversion/bindings/swig/include/proxy_apr.swg (working copy) @@ -39,6 +39,10 @@ self.assert_valid() return self.this +def _mark_weakpool_invalid(weakpool): + if weakpool and weakpool() and hasattr(weakpool(), "_is_valid"): + del weakpool()._is_valid + %} struct apr_pool_t { @@ -61,9 +65,9 @@ if not self._parent_pool: svn_swig_py_set_application_pool(self, self) application_pool = self + + assert hasattr(self,"_wrap") - svn_swig_py_register_cleanup(self, self) - def valid(self): """Check whether this memory pool and its parents are still valid""" @@ -91,13 +95,14 @@ # Destroy pool self._apr_pool_destroy(self) - + # Clear application pool if necessary if is_application_pool: application_pool = None self._svn_swig_py_clear_application_pool() - del self._parent_pool + # Mark self as invalid + del self._is_valid def __del__(self): """Automatically destroy memory pools, if necessary""" @@ -106,9 +111,23 @@ def _mark_valid(self): """Mark pool as valid""" + + self._weakparent = None + if self._parent_pool: + import weakref + # Make sure that the parent object is valid - self._parent_pool.assert_valid(); + self._parent_pool.assert_valid() + + # Refer to self using a weakrefrence so that we don't + # create a reference cycle + weakself = weakref.ref(self) + + # Set up callbacks to mark pool as invalid when parents + # are destroyed + self._weakparent = weakref.ref(self._parent_pool._is_valid, + lambda x: _mark_weakpool_invalid(weakself)) # Mark pool as valid self._is_valid = lambda: 1