Skip to content

Commit 89004d7

Browse files
authored
[3.5] bpo-30414: multiprocessing.Queue._feed do not break from main loop on exc (GH-1683) (#1816)
* bpo-30414: multiprocesing.Queue._feed do not break from main loop on exc Queue background running thread was not handling exceptions correctly. Any exception occurred inside thread (putting unpickable object) cause feeder to finish running. After that every message put into queue is silently ignored. * bpo-30414: multiprocesing.Queue._feed do not break from main loop on exc Queue background running thread was not handling exceptions correctly. Any exception occurred inside thread (putting unpickable object) cause feeder to finish running. After that every message put into queue is silently ignored. (cherry picked from commit bc50f03)
1 parent aa27f0e commit 89004d7

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

Lib/multiprocessing/queues.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe):
221221
else:
222222
wacquire = None
223223

224-
try:
225-
while 1:
224+
while 1:
225+
try:
226226
nacquire()
227227
try:
228228
if not buffer:
@@ -249,21 +249,19 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe):
249249
wrelease()
250250
except IndexError:
251251
pass
252-
except Exception as e:
253-
if ignore_epipe and getattr(e, 'errno', 0) == errno.EPIPE:
254-
return
255-
# Since this runs in a daemon thread the resources it uses
256-
# may be become unusable while the process is cleaning up.
257-
# We ignore errors which happen after the process has
258-
# started to cleanup.
259-
try:
252+
except Exception as e:
253+
if ignore_epipe and getattr(e, 'errno', 0) == errno.EPIPE:
254+
return
255+
# Since this runs in a daemon thread the resources it uses
256+
# may be become unusable while the process is cleaning up.
257+
# We ignore errors which happen after the process has
258+
# started to cleanup.
260259
if is_exiting():
261260
info('error in queue thread: %s', e)
261+
return
262262
else:
263263
import traceback
264264
traceback.print_exc()
265-
except Exception:
266-
pass
267265

268266
_sentinel = object()
269267

Lib/test/_test_multiprocessing.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,20 @@ def test_timeout(self):
752752
# Windows (usually 15.6 ms)
753753
self.assertGreaterEqual(delta, 0.170)
754754

755+
def test_queue_feeder_donot_stop_onexc(self):
756+
# bpo-30414: verify feeder handles exceptions correctly
757+
if self.TYPE != 'processes':
758+
self.skipTest('test not appropriate for {}'.format(self.TYPE))
759+
760+
class NotSerializable(object):
761+
def __reduce__(self):
762+
raise AttributeError
763+
with test.support.captured_stderr():
764+
q = self.Queue()
765+
q.put(NotSerializable())
766+
q.put(True)
767+
self.assertTrue(q.get(timeout=0.1))
768+
755769
#
756770
#
757771
#

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ Extension Modules
5656
Library
5757
-------
5858

59+
- bpo-30414: multiprocessing.Queue._feed background running
60+
thread do not break from main loop on exception.
61+
5962
- bpo-30003: Fix handling escape characters in HZ codec. Based on patch
6063
by Ma Lin.
6164

0 commit comments

Comments
 (0)