]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
put() doesn't defer unblocking get().
authorA. Jesse Jiryu Davis <jesse@mongodb.com>
Sun, 15 Mar 2015 21:41:55 +0000 (17:41 -0400)
committerA. Jesse Jiryu Davis <jesse@mongodb.com>
Sun, 15 Mar 2015 21:51:04 +0000 (17:51 -0400)
tornado/queues.py
tornado/test/queues_test.py

index e2aec50afbdd5569d239dfaaed25803b95da3fb9..562fc6c55d5c8d348d2df83faf9a291da35bb567 100644 (file)
@@ -129,11 +129,7 @@ class Queue(object):
 
         if self.qsize():
             future = Future()
-            # Defer unblocking the getter, which might do task_done() without
-            # yielding first. We want putters to have a chance to run first and
-            # keep join() blocked. See test_producer_consumer().
-            ioloop.IOLoop.current().add_callback(
-                partial(future.set_result, self._get()))
+            future.set_result(self._get())
             return future
         else:
             future = Future()
index 880db822491f383cf1d86ad72b327472bcfa8af0..34b611315c9431a51840a0c1419769a5c834823f 100644 (file)
@@ -289,6 +289,20 @@ class QueueJoinTest(AsyncTestCase):
         yield q.join()
         self.assertEqual(sum(range(100)), self.accumulator)
 
+    @gen_test
+    def test_task_done_delay(self):
+        # Verify it is task_done(), not get(), that unblocks join().
+        q = queues.Queue()
+        q.put_nowait(0)
+        join = q.join()
+        self.assertFalse(join.done())
+        yield q.get()
+        self.assertFalse(join.done())
+        yield gen.moment
+        self.assertFalse(join.done())
+        q.task_done()
+        self.assertTrue(join.done())
+
     @gen_test
     def test_join_empty_queue(self):
         q = queues.Queue()
@@ -310,8 +324,7 @@ class QueueJoinTest(AsyncTestCase):
         # We don't yield between get() and task_done(), so get() must wait for
         # the next tick. Otherwise we'd immediately call task_done and unblock
         # join() before q.put() resumes, and we'd only process the first four
-        # items. Consumers would normally yield in the course of processing an
-        # item, but it's worthwhile testing the degenerate case.
+        # items.
         @gen.coroutine
         def consumer():
             while True:
@@ -323,8 +336,8 @@ class QueueJoinTest(AsyncTestCase):
             for item in range(10):
                 yield q.put(item)
 
-        producer()
         consumer()
+        yield producer()
         yield q.join()
         self.assertEqual(list(range(10)), history)