From 5d490b353ab75d42e733f24dba30ec5131b13dca Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 4 Apr 2024 12:05:59 +1000 Subject: [PATCH 1/7] Unblock getters after non-immediate queue shutdown --- Lib/queue.py | 2 +- Lib/test/test_queue.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Lib/queue.py b/Lib/queue.py index 387ce5425879a4..cccad7dcff87ce 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -249,9 +249,9 @@ def shutdown(self, immediate=False): self._get() if self.unfinished_tasks > 0: self.unfinished_tasks -= 1 - self.not_empty.notify_all() # release all blocked threads in `join()` self.all_tasks_done.notify_all() + self.not_empty.notify_all() self.not_full.notify_all() # Override these methods to implement other queue organizations diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index c4d10110132393..c41a5e4141c274 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -636,6 +636,23 @@ def test_shutdown_get_task_done_join(self): self.assertEqual(results, [True]*len(thrds)) + def test_shutdown_get_simple(self): + def get(): + try: + results.append(q.get()) + except Exception as e: + results.append(e) + + q = self.type2test() + results = [] + get_thread = threading.Thread(target=get) + get_thread.start() + q.shutdown() + get_thread.join(timeout=0.01) + self.assertFalse(get_thread.is_alive()) + self.assertEqual(len(results), 1) + self.assertIsInstance(results[0], self.queue.ShutDown) + class QueueTest(BaseQueueTestMixin): From 076122da85a19138c8c18ecf59227f5b59a88022 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 4 Apr 2024 13:53:12 +1000 Subject: [PATCH 2/7] Increase join timeout in test --- Lib/test/test_queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index c41a5e4141c274..09f2d40cee36c4 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -648,7 +648,7 @@ def get(): get_thread = threading.Thread(target=get) get_thread.start() q.shutdown() - get_thread.join(timeout=0.01) + get_thread.join(timeout=10.0) self.assertFalse(get_thread.is_alive()) self.assertEqual(len(results), 1) self.assertIsInstance(results[0], self.queue.ShutDown) From 5c709bf3ccc71f2df40f50dab54818c95899e1e8 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 4 Apr 2024 18:47:21 +1000 Subject: [PATCH 3/7] Improve test name --- Lib/test/test_queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 09f2d40cee36c4..45c202a1399695 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -636,7 +636,7 @@ def test_shutdown_get_task_done_join(self): self.assertEqual(results, [True]*len(thrds)) - def test_shutdown_get_simple(self): + def test_shutdown_pending_get(self): def get(): try: results.append(q.get()) From f935277af4fac062f12e0b40d9fb6dd62dc43f48 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 4 Apr 2024 18:49:16 +1000 Subject: [PATCH 4/7] Explicit non-immediate shutdown in test --- Lib/test/test_queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_queue.py b/Lib/test/test_queue.py index 45c202a1399695..d5927fbf39142b 100644 --- a/Lib/test/test_queue.py +++ b/Lib/test/test_queue.py @@ -647,7 +647,7 @@ def get(): results = [] get_thread = threading.Thread(target=get) get_thread.start() - q.shutdown() + q.shutdown(immediate=False) get_thread.join(timeout=10.0) self.assertFalse(get_thread.is_alive()) self.assertEqual(len(results), 1) From 61d2010de747c1c051b23c7f72722bbb69a7fbd3 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Mon, 8 Apr 2024 15:01:29 +1000 Subject: [PATCH 5/7] Mention gets are always unblocked --- Doc/library/queue.rst | 6 ++++-- Lib/queue.py | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index f2a6dbf589fd87..fce23313c7de28 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -245,8 +245,10 @@ them down. queue is empty. Set *immediate* to true to make :meth:`~Queue.get` raise immediately instead. - All blocked callers of :meth:`~Queue.put` will be unblocked. If *immediate* - is true, also unblock callers of :meth:`~Queue.get` and :meth:`~Queue.join`. + All blocked callers of :meth:`~Queue.put` and :meth:`~Queue.get` will be + unblocked. If *immediate* is true, a task will be marked as done for each + remaining item in the queue, which may unblock callers of + :meth:`~Queue.join`. .. versionadded:: 3.13 diff --git a/Lib/queue.py b/Lib/queue.py index cccad7dcff87ce..d68c8b757a6ac5 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -239,8 +239,9 @@ def shutdown(self, immediate=False): By default, gets will only raise once the queue is empty. Set 'immediate' to True to make gets raise immediately instead. - All blocked callers of put() will be unblocked, and also get() - and join() if 'immediate'. + All blocked callers of put() and get() will be unblocked. If + 'immediate', a task is marked as done for each item remaining in + the queue, which may unblock callers of join(). ''' with self.mutex: self.is_shutdown = True From a67af7aa1b7ce9519be113c5416a1f13ae98d899 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Mon, 8 Apr 2024 15:02:25 +1000 Subject: [PATCH 6/7] Comment reason for waking-up getters after shutdown --- Lib/queue.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/queue.py b/Lib/queue.py index d68c8b757a6ac5..45b86e6f472d6c 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -253,6 +253,7 @@ def shutdown(self, immediate=False): # release all blocked threads in `join()` self.all_tasks_done.notify_all() self.not_empty.notify_all() + # All getters need to re-check queue-empty to raise ShutDown self.not_full.notify_all() # Override these methods to implement other queue organizations From dbb2190b7477cef939c21aff2de91850d3dc3a2a Mon Sep 17 00:00:00 2001 From: Laurie O Date: Tue, 9 Apr 2024 10:36:21 +1000 Subject: [PATCH 7/7] Move comment to correct position --- Lib/queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/queue.py b/Lib/queue.py index 45b86e6f472d6c..25beb46e30d6bd 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -252,8 +252,8 @@ def shutdown(self, immediate=False): self.unfinished_tasks -= 1 # release all blocked threads in `join()` self.all_tasks_done.notify_all() - self.not_empty.notify_all() # All getters need to re-check queue-empty to raise ShutDown + self.not_empty.notify_all() self.not_full.notify_all() # Override these methods to implement other queue organizations pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy