mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
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:
commit
723585bbaf
3 changed files with 61 additions and 7 deletions
|
@ -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
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue