rendered paste bodyIndex: 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)
@@ -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)
{
@@ -203,6 +158,9 @@
}
} else {
result = PyObject_CallMethod(pool, wrap, objectTuple, *proxy);
+ if (result == NULL) {
+ return 1;
+ }
Py_DECREF(*proxy);
*proxy = result;
}
@@ -380,9 +338,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