summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorCharles-François Natali <neologix@free.fr>2011-07-02 12:39:53 (GMT)
committerCharles-François Natali <neologix@free.fr>2011-07-02 12:39:53 (GMT)
commita4a04069fd93395369b6061ed07f471e53f1c7a1 (patch)
tree3bb1e52b4690c7d30d5a4cf39e514ae37e04403b /Lib/test
parentee1a7cb4a44caf44e7f56db7645381da78cf6ffd (diff)
parent778db49da9eeb23af4410f592165d7e46d4a285a (diff)
downloadcpython-a4a04069fd93395369b6061ed07f471e53f1c7a1.zip
cpython-a4a04069fd93395369b6061ed07f471e53f1c7a1.tar.gz
cpython-a4a04069fd93395369b6061ed07f471e53f1c7a1.tar.bz2
Merge issue #12352: Fix a deadlock in multiprocessing.Heap when a block is
freed by the garbage collector while the Heap lock is held.
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_multiprocessing.py24
1 files changed, 24 insertions, 0 deletions
diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py
index dc41e15..654cffb 100644
--- a/Lib/test/test_multiprocessing.py
+++ b/Lib/test/test_multiprocessing.py
@@ -1672,6 +1672,8 @@ class _TestHeap(BaseTestCase):
# verify the state of the heap
all = []
occupied = 0
+ heap._lock.acquire()
+ self.addCleanup(heap._lock.release)
for L in list(heap._len_to_seq.values()):
for arena, start, stop in L:
all.append((heap._arenas.index(arena), start, stop,
@@ -1689,6 +1691,28 @@ class _TestHeap(BaseTestCase):
self.assertTrue((arena != narena and nstart == 0) or
(stop == nstart))
+ def test_free_from_gc(self):
+ # Check that freeing of blocks by the garbage collector doesn't deadlock
+ # (issue #12352).
+ # Make sure the GC is enabled, and set lower collection thresholds to
+ # make collections more frequent (and increase the probability of
+ # deadlock).
+ if not gc.isenabled():
+ gc.enable()
+ self.addCleanup(gc.disable)
+ thresholds = gc.get_threshold()
+ self.addCleanup(gc.set_threshold, *thresholds)
+ gc.set_threshold(10)
+
+ # perform numerous block allocations, with cyclic references to make
+ # sure objects are collected asynchronously by the gc
+ for i in range(5000):
+ a = multiprocessing.heap.BufferWrapper(1)
+ b = multiprocessing.heap.BufferWrapper(1)
+ # circular references
+ a.buddy = b
+ b.buddy = a
+
#
#
#