Commit 8ee370f4 authored by Richard Oudkerk's avatar Richard Oudkerk

Issue #17555: Fix ForkAwareThreadLock so that size of after fork

registry does not grow exponentially with generation of process.
parent 9cfa53ac
...@@ -329,10 +329,13 @@ atexit.register(_exit_function) ...@@ -329,10 +329,13 @@ atexit.register(_exit_function)
class ForkAwareThreadLock(object): class ForkAwareThreadLock(object):
def __init__(self): def __init__(self):
self._reset()
register_after_fork(self, ForkAwareThreadLock._reset)
def _reset(self):
self._lock = threading.Lock() self._lock = threading.Lock()
self.acquire = self._lock.acquire self.acquire = self._lock.acquire
self.release = self._lock.release self.release = self._lock.release
register_after_fork(self, ForkAwareThreadLock.__init__)
class ForkAwareLocal(threading.local): class ForkAwareLocal(threading.local):
def __init__(self): def __init__(self):
......
...@@ -2430,13 +2430,43 @@ class TestFlags(unittest.TestCase): ...@@ -2430,13 +2430,43 @@ class TestFlags(unittest.TestCase):
[sys.executable, '-E', '-B', '-O', '-c', prog]) [sys.executable, '-E', '-B', '-O', '-c', prog])
child_flags, grandchild_flags = json.loads(data.decode('ascii')) child_flags, grandchild_flags = json.loads(data.decode('ascii'))
self.assertEqual(child_flags, grandchild_flags) self.assertEqual(child_flags, grandchild_flags)
#
# Issue #17555: ForkAwareThreadLock
#
class TestForkAwareThreadLock(unittest.TestCase):
# We recurisvely start processes. Issue #17555 meant that the
# after fork registry would get duplicate entries for the same
# lock. The size of the registry at generation n was ~2**n.
@classmethod
def child(cls, n, conn):
if n > 1:
p = multiprocessing.Process(target=cls.child, args=(n-1, conn))
p.start()
p.join()
else:
conn.send(len(util._afterfork_registry))
conn.close()
def test_lock(self):
r, w = multiprocessing.Pipe(False)
l = util.ForkAwareThreadLock()
old_size = len(util._afterfork_registry)
p = multiprocessing.Process(target=self.child, args=(5, w))
p.start()
new_size = r.recv()
p.join()
self.assertLessEqual(new_size, old_size)
# #
# #
# #
testcases_other = [OtherTest, TestInvalidHandle, TestInitializers, testcases_other = [OtherTest, TestInvalidHandle, TestInitializers,
TestStdinBadfiledescriptor, TestTimeouts, TestNoForkBomb, TestStdinBadfiledescriptor, TestTimeouts, TestNoForkBomb,
TestFlags] TestFlags, TestForkAwareThreadLock]
# #
# #
......
...@@ -28,6 +28,9 @@ Core and Builtins ...@@ -28,6 +28,9 @@ Core and Builtins
Library Library
------- -------
- Issue #17555: Fix ForkAwareThreadLock so that size of after fork
registry does not grow exponentially with generation of process.
- Issue #17710: Fix cPickle raising a SystemError on bogus input. - Issue #17710: Fix cPickle raising a SystemError on bogus input.
- Issue #17341: Include the invalid name in the error messages from re about - Issue #17341: Include the invalid name in the error messages from re about
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment