Index: subversion/bindings/swig/core.i =================================================================== --- subversion/bindings/swig/core.i (revision 16805) +++ subversion/bindings/swig/core.i (revision 16807) @@ -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/svn/core.py =================================================================== --- subversion/bindings/swig/python/svn/core.py (revision 16805) +++ subversion/bindings/swig/python/svn/core.py (revision 16807) @@ -18,6 +18,8 @@ from libsvn.core import * import libsvn.core as _core +import atexit as _atexit +_atexit.register(lambda: _core.application_pool.destroy()) def _unprefix_names(symbol_dict, from_prefix, to_prefix = ''): for name, value in symbol_dict.items(): Index: subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c =================================================================== --- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (revision 16805) +++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (revision 16807) @@ -103,7 +103,6 @@ static PyObject *_global_svn_swig_py_pool = NULL; static char assertValid[] = "assert_valid"; static char parentPool[] = "_parent_pool"; -static char isValid[] = "_is_valid"; static char wrap[] = "_wrap"; static char unwrap[] = "_unwrap"; static char setParentPool[] = "set_parent_pool"; @@ -136,50 +135,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) { @@ -373,24 +328,14 @@ /* Functions for making Python wrappers around Subversion structs */ static PyObject *make_ob_pool(void *pool) { - PyObject *py_pool = SWIG_NewPointerObj(pool, - svn_swig_TypeQuery("apr_pool_t *"), 0); - - if (py_pool == NULL) { - 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; - } - - Py_INCREF(py_pool); - - return py_pool; + /* Return a brand new default pool to Python. This pool isn't + * normally used for anything. It's just here for compatibility + * with Subversion 1.2. */ + (void) pool; + apr_pool_t *new_pool = svn_pool_create(_global_pool); + PyObject *new_py_pool = svn_swig_NewPointerObj(new_pool, + svn_swig_TypeQuery("apr_pool_t *"), _global_svn_swig_py_pool); + return new_py_pool; } static PyObject *make_ob_fs_root(svn_fs_root_t *ptr, PyObject *py_pool) { Index: subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h =================================================================== --- subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (revision 16805) +++ subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (revision 16807) @@ -79,10 +79,6 @@ SVN_SWIG_SWIGUTIL_EXPORT void svn_swig_get_application_pool(PyObject **py_pool, apr_pool_t **pool); -/* Register cleanup function */ -SVN_SWIG_SWIGUTIL_EXPORT -PyObject * svn_swig_py_register_cleanup(PyObject *py_pool, apr_pool_t *pool); - /*** SWIG Wrappers ***/ Index: subversion/bindings/swig/include/proxy_apr.swg =================================================================== --- subversion/bindings/swig/include/proxy_apr.swg (revision 16805) +++ subversion/bindings/swig/include/proxy_apr.swg (revision 16807) @@ -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 { @@ -62,8 +66,6 @@ svn_swig_py_set_application_pool(self, self) application_pool = self - svn_swig_py_register_cleanup(self, self) - def valid(self): """Check whether this memory pool and its parents are still valid""" @@ -97,7 +99,11 @@ application_pool = None self._svn_swig_py_clear_application_pool() - del self._parent_pool + # Mark self as invalid + if hasattr(self, "_parent_pool"): + del self._parent_pool + if hasattr(self, "_is_valid"): + del self._is_valid def __del__(self): """Automatically destroy memory pools, if necessary""" @@ -106,9 +112,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