Author: svn-role
Date: Sat May 8 04:00:13 2021
New Revision: 1889654
URL: http://svn.apache.org/viewvc?rev=1889654&view=rev
Log:
Merge r1889487 from trunk:
* r1889487
swig-py: Fix doubly destroying memory pool with cyclic garbage collector.
Votes:
+1: jun66j5, futatuki
Modified:
subversion/branches/1.14.x/ (props changed)
subversion/branches/1.14.x/STATUS
subversion/branches/1.14.x/subversion/bindings/swig/include/proxy_apr.swg
subversion/branches/1.14.x/subversion/bindings/swig/python/tests/pool.py
Propchange: subversion/branches/1.14.x/
------------------------------------------------------------------------------
Merged /subversion/trunk:r1889487
Modified: subversion/branches/1.14.x/STATUS
URL:
http://svn.apache.org/viewvc/subversion/branches/1.14.x/STATUS?rev=1889654&r1=1889653&r2=1889654&view=diff
==============================================================================
--- subversion/branches/1.14.x/STATUS (original)
+++ subversion/branches/1.14.x/STATUS Sat May 8 04:00:13 2021
@@ -99,8 +99,3 @@ Veto-blocked changes:
Approved changes:
=================
-
- * r1889487
- swig-py: Fix doubly destroying memory pool with cyclic garbage collector.
- Votes:
- +1: jun66j5, futatuki
Modified:
subversion/branches/1.14.x/subversion/bindings/swig/include/proxy_apr.swg
URL:
http://svn.apache.org/viewvc/subversion/branches/1.14.x/subversion/bindings/swig/include/proxy_apr.swg?rev=1889654&r1=1889653&r2=1889654&view=diff
==============================================================================
--- subversion/branches/1.14.x/subversion/bindings/swig/include/proxy_apr.swg
(original)
+++ subversion/branches/1.14.x/subversion/bindings/swig/include/proxy_apr.swg
Sat May 8 04:00:13 2021
@@ -142,9 +142,15 @@ struct apr_pool_t {
are still valid"""
try:
self._is_valid
- return True
except AttributeError:
return False
+ # We must check whether the parent pool is valid even if
+ # the pool is valid because weakref's callback is not
+ # invoked when it is finalized by cyclic garbage collector
+ if self._parent_pool:
+ return self._parent_pool.valid()
+ else:
+ return True
def assert_valid(self):
"""Assert that this memory_pool is still valid."""
Modified:
subversion/branches/1.14.x/subversion/bindings/swig/python/tests/pool.py
URL:
http://svn.apache.org/viewvc/subversion/branches/1.14.x/subversion/bindings/swig/python/tests/pool.py?rev=1889654&r1=1889653&r2=1889654&view=diff
==============================================================================
--- subversion/branches/1.14.x/subversion/bindings/swig/python/tests/pool.py
(original)
+++ subversion/branches/1.14.x/subversion/bindings/swig/python/tests/pool.py
Sat May 8 04:00:13 2021
@@ -19,10 +19,11 @@
#
#
import unittest, weakref, setup_path
-import os, tempfile
+import os, tempfile, gc
import svn.core, svn.client, libsvn.core
from svn.core import *
from libsvn.core import application_pool, GenericSWIGWrapper
+import utils
# Test case for the new automatic pool management infrastructure
@@ -208,6 +209,51 @@ class PoolTestCase(unittest.TestCase):
# We can still destroy and create pools at will
svn_pool_destroy(svn_pool_create())
+ def _test_pools_in_circular_reference(self, finalizer=False):
+
+ class Circular(object):
+
+ def __init__(self, pool):
+ self.pool = pool
+ self.loop = None
+
+ if finalizer:
+ def __del__(self):
+ self.pool = self.loop = None
+
+ def create_circularl():
+ pool = Pool(libsvn.core.application_pool)
+ subpool1 = Pool(pool)
+ subpool2 = Pool(pool)
+ circularly1 = Circular(pool)
+ circularly2 = Circular(subpool2)
+ circularly3 = Circular(subpool1)
+ circularly1.loop = circularly3
+ circularly2.loop = circularly1
+ circularly3.loop = circularly2
+ refs = weakref.WeakValueDictionary()
+ refs['pool'] = pool
+ refs['subpool1'] = subpool1
+ refs['subpool2'] = subpool2
+ return refs
+
+ refs = create_circularl()
+ self.assertEqual({'pool', 'subpool1', 'subpool2'},
+ set(name for name, pool in refs.items()
+ if pool is not None))
+ gc.collect()
+ self.assertEqual(set(), set(name for name, pool in refs.items()
+ if pool is not None))
+
+ def test_pools_in_circular_reference_without_finalizer(self):
+ self._test_pools_in_circular_reference(finalizer=False)
+
+ @unittest.skipIf(not utils.IS_PY3,
+ "Python 2 cannot collect garbage which involves circular "
+ "references with finalizer")
+ def test_pools_in_circular_reference_with_finalizer(self):
+ self._test_pools_in_circular_reference(finalizer=True)
+
def suite():
return unittest.defaultTestLoader.loadTestsFromTestCase(PoolTestCase)