Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9a1b956

Browse files
committed
merge heads
2 parents 1fafc1a + 64c1c07 commit 9a1b956

4 files changed

Lines changed: 37 additions & 5 deletions

File tree

Lib/multiprocessing/pool.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,11 @@ def map_async(self, func, iterable, chunksize=None, callback=None,
321321

322322
@staticmethod
323323
def _handle_workers(pool):
324-
while pool._worker_handler._state == RUN and pool._state == RUN:
324+
thread = threading.current_thread()
325+
326+
# Keep maintaining workers until the cache gets drained, unless the pool
327+
# is terminated.
328+
while thread._state == RUN or (pool._cache and thread._state != TERMINATE):
325329
pool._maintain_pool()
326330
time.sleep(0.1)
327331
# send sentinel to stop workers

Lib/test/test_multiprocessing.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,20 @@ def test_pool_worker_lifetime(self):
12171217
p.close()
12181218
p.join()
12191219

1220+
def test_pool_worker_lifetime_early_close(self):
1221+
# Issue #10332: closing a pool whose workers have limited lifetimes
1222+
# before all the tasks completed would make join() hang.
1223+
p = multiprocessing.Pool(3, maxtasksperchild=1)
1224+
results = []
1225+
for i in range(6):
1226+
results.append(p.apply_async(sqr, (i, 0.3)))
1227+
p.close()
1228+
p.join()
1229+
# check the results
1230+
for (j, res) in enumerate(results):
1231+
self.assertEqual(res.get(), sqr(j))
1232+
1233+
12201234
#
12211235
# Test that manager has expected number of shared objects left
12221236
#

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.2.3?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #13018: Fix reference leaks in error paths in dictobject.c.
14+
Patch by Suman Saha.
15+
1316
- Issue #1294232: In a few cases involving metaclass inheritance, the
1417
interpreter would sometimes invoke the wrong metaclass when building a new
1518
class object. These cases now behave correctly. Patch by Daniel Urban.
@@ -58,6 +61,9 @@ Core and Builtins
5861
Library
5962
-------
6063

64+
- Issue #10332: multiprocessing: fix a race condition when a Pool is closed
65+
before all tasks have completed.
66+
6167
- Issue #13255: wrong docstrings in array module.
6268

6369
- Issue #9168: now smtpd is able to bind privileged port.

Objects/dictobject.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,14 +1314,18 @@ dict_fromkeys(PyObject *cls, PyObject *args)
13141314
PyObject *key;
13151315
Py_hash_t hash;
13161316

1317-
if (dictresize(mp, Py_SIZE(seq)))
1317+
if (dictresize(mp, Py_SIZE(seq))) {
1318+
Py_DECREF(d);
13181319
return NULL;
1320+
}
13191321

13201322
while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) {
13211323
Py_INCREF(key);
13221324
Py_INCREF(value);
1323-
if (insertdict(mp, key, hash, value))
1325+
if (insertdict(mp, key, hash, value)) {
1326+
Py_DECREF(d);
13241327
return NULL;
1328+
}
13251329
}
13261330
return d;
13271331
}
@@ -1332,14 +1336,18 @@ dict_fromkeys(PyObject *cls, PyObject *args)
13321336
PyObject *key;
13331337
Py_hash_t hash;
13341338

1335-
if (dictresize(mp, PySet_GET_SIZE(seq)))
1339+
if (dictresize(mp, PySet_GET_SIZE(seq))) {
1340+
Py_DECREF(d);
13361341
return NULL;
1342+
}
13371343

13381344
while (_PySet_NextEntry(seq, &pos, &key, &hash)) {
13391345
Py_INCREF(key);
13401346
Py_INCREF(value);
1341-
if (insertdict(mp, key, hash, value))
1347+
if (insertdict(mp, key, hash, value)) {
1348+
Py_DECREF(d);
13421349
return NULL;
1350+
}
13431351
}
13441352
return d;
13451353
}

0 commit comments

Comments
 (0)