Workaround for a race condition on queue invalidation, Issue #2078

This commit is contained in:
wordofglass 2016-06-29 18:22:44 +02:00
parent 10a47e98d0
commit ebf44fd6cd
2 changed files with 11 additions and 2 deletions

View file

@ -64,7 +64,17 @@ def _invalidate_queue(q, val=None, sync=True):
q.mutex.acquire()
try:
q.maxsize = 0
# Originally, we set `maxsize` to 0 here, which is supposed to mean
# an unlimited queue size. However, there is a race condition since
# Python 3.2 when this attribute is changed while another thread is
# waiting in put()/get() due to a full/empty queue.
# Setting it to 2 is still hacky because Python does not give any
# guarantee what happens if Queue methods/attributes are overwritten
# when it is already in use. However, because of our dummy _put()
# and _get() methods, it provides a workaround to let the queue appear
# to be never empty or full.
# See issue https://github.com/beetbox/beets/issues/2078
q.maxsize = 2
q._qsize = _qsize
q._put = _put
q._get = _get

View file

@ -162,7 +162,6 @@ class ConstrainedThreadedPipelineTest(unittest.TestCase):
pl.run_parallel(1)
self.assertEqual(l, [i * 2 for i in range(1000)])
@unittest.skipIf(six.PY3, u'freezes the test suite in py3')
def test_constrained_exception(self):
# Raise an exception in a constrained pipeline.
l = []