Skip to content

Commit e2f33ad

Browse files
tomMoralpitrou
authored andcommitted
bpo-33078 - Fix queue size on pickling error (GH-6119)
1 parent 9308dea commit e2f33ad

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

Lib/multiprocessing/queues.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def _start_thread(self):
161161
target=Queue._feed,
162162
args=(self._buffer, self._notempty, self._send_bytes,
163163
self._wlock, self._writer.close, self._ignore_epipe,
164-
self._on_queue_feeder_error),
164+
self._on_queue_feeder_error, self._sem),
165165
name='QueueFeederThread'
166166
)
167167
self._thread.daemon = True
@@ -203,7 +203,7 @@ def _finalize_close(buffer, notempty):
203203

204204
@staticmethod
205205
def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe,
206-
onerror):
206+
onerror, queue_sem):
207207
debug('starting thread to feed data to pipe')
208208
nacquire = notempty.acquire
209209
nrelease = notempty.release
@@ -255,6 +255,12 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe,
255255
info('error in queue thread: %s', e)
256256
return
257257
else:
258+
# Since the object has not been sent in the queue, we need
259+
# to decrease the size of the queue. The error acts as
260+
# if the object had been silently removed from the queue
261+
# and this step is necessary to have a properly working
262+
# queue.
263+
queue_sem.release()
258264
onerror(e, obj)
259265

260266
@staticmethod

Lib/test/_test_multiprocessing.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,19 @@ def __reduce__(self):
10561056
self.assertTrue(q.get(timeout=1.0))
10571057
close_queue(q)
10581058

1059+
with test.support.captured_stderr():
1060+
# bpo-33078: verify that the queue size is correctly handled
1061+
# on errors.
1062+
q = self.Queue(maxsize=1)
1063+
q.put(NotSerializable())
1064+
q.put(True)
1065+
self.assertEqual(q.qsize(), 1)
1066+
# bpo-30595: use a timeout of 1 second for slow buildbots
1067+
self.assertTrue(q.get(timeout=1.0))
1068+
# Check that the size of the queue is correct
1069+
self.assertEqual(q.qsize(), 0)
1070+
close_queue(q)
1071+
10591072
def test_queue_feeder_on_queue_feeder_error(self):
10601073
# bpo-30006: verify feeder handles exceptions using the
10611074
# _on_queue_feeder_error hook.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix the size handling in multiprocessing.Queue when a pickling error
2+
occurs.

0 commit comments

Comments
 (0)