mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-109593: Fix reentrancy issue in multiprocessing resource_tracker (#109629)
--------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
This commit is contained in:
parent
2897142d2e
commit
0eb98837b6
7 changed files with 95 additions and 2 deletions
|
@ -330,6 +330,42 @@ class RLockTests(BaseLockTests):
|
|||
lock.release()
|
||||
self.assertRaises(RuntimeError, lock._release_save)
|
||||
|
||||
def test_recursion_count(self):
|
||||
lock = self.locktype()
|
||||
self.assertEqual(0, lock._recursion_count())
|
||||
lock.acquire()
|
||||
self.assertEqual(1, lock._recursion_count())
|
||||
lock.acquire()
|
||||
lock.acquire()
|
||||
self.assertEqual(3, lock._recursion_count())
|
||||
lock.release()
|
||||
self.assertEqual(2, lock._recursion_count())
|
||||
lock.release()
|
||||
lock.release()
|
||||
self.assertEqual(0, lock._recursion_count())
|
||||
|
||||
phase = []
|
||||
|
||||
def f():
|
||||
lock.acquire()
|
||||
phase.append(None)
|
||||
while len(phase) == 1:
|
||||
_wait()
|
||||
lock.release()
|
||||
phase.append(None)
|
||||
|
||||
with threading_helper.wait_threads_exit():
|
||||
start_new_thread(f, ())
|
||||
while len(phase) == 0:
|
||||
_wait()
|
||||
self.assertEqual(len(phase), 1)
|
||||
self.assertEqual(0, lock._recursion_count())
|
||||
phase.append(None)
|
||||
while len(phase) == 2:
|
||||
_wait()
|
||||
self.assertEqual(len(phase), 3)
|
||||
self.assertEqual(0, lock._recursion_count())
|
||||
|
||||
def test_different_thread(self):
|
||||
# Cannot release from a different thread
|
||||
lock = self.locktype()
|
||||
|
|
|
@ -29,6 +29,8 @@ class ModuleLockAsRLockTests:
|
|||
test_timeout = None
|
||||
# _release_save() unsupported
|
||||
test_release_save_unacquired = None
|
||||
# _recursion_count() unsupported
|
||||
test_recursion_count = None
|
||||
# lock status in repr unsupported
|
||||
test_repr = None
|
||||
test_locked_repr = None
|
||||
|
|
|
@ -1783,6 +1783,9 @@ class ConditionAsRLockTests(lock_tests.RLockTests):
|
|||
# Condition uses an RLock by default and exports its API.
|
||||
locktype = staticmethod(threading.Condition)
|
||||
|
||||
def test_recursion_count(self):
|
||||
self.skipTest("Condition does not expose _recursion_count()")
|
||||
|
||||
class ConditionTests(lock_tests.ConditionTests):
|
||||
condtype = staticmethod(threading.Condition)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue