Merge issue #12352: Fix a deadlock in multiprocessing.Heap when a block is

freed by the garbage collector while the Heap lock is held.
This commit is contained in:
Charles-François Natali 2011-07-02 14:43:11 +02:00
commit 723585bbaf
3 changed files with 61 additions and 7 deletions

View file

@ -1721,6 +1721,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,
@ -1738,6 +1740,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
#
#
#