From 4a8395a4d2391674449393058ac9a4916562d32a Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Wed, 2 Oct 2019 23:32:19 -0400 Subject: [PATCH 1/5] Fix test_asyncio.test_subprocess dangling threads --- Lib/asyncio/unix_events.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index d8f653045aee4c..670488a76ba1d4 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1266,7 +1266,14 @@ def is_active(self): return True def close(self): - pass + self._join_threads() + + def _join_threads(self): + threads = [thread for thread in list(self._threads.values()) + if thread.is_alive()] + + for thread in threads: + thread.join() def __enter__(self): return self From bfc0d6c075d8a3827daad371021c5f726767810a Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Wed, 2 Oct 2019 23:59:23 -0400 Subject: [PATCH 2/5] Remove empty line and fix formatting --- Lib/asyncio/unix_events.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 670488a76ba1d4..dbe6ece9b36ae4 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1270,8 +1270,7 @@ def close(self): def _join_threads(self): threads = [thread for thread in list(self._threads.values()) - if thread.is_alive()] - + if thread.is_alive()] for thread in threads: thread.join() @@ -1283,7 +1282,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): def __del__(self, _warn=warnings.warn): threads = [thread for thread in list(self._threads.values()) - if thread.is_alive()] + if thread.is_alive()] if threads: _warn(f"{self.__class__} has registered but not finished child processes", ResourceWarning, From fbf7f0dd76531a9a6028cc21eebb087b817966a9 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 24 Oct 2019 03:18:09 -0400 Subject: [PATCH 3/5] Fix code formatting --- Lib/asyncio/unix_events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index dbe6ece9b36ae4..18845c7493c2e7 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1270,7 +1270,7 @@ def close(self): def _join_threads(self): threads = [thread for thread in list(self._threads.values()) - if thread.is_alive()] + if thread.is_alive()] for thread in threads: thread.join() @@ -1282,7 +1282,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): def __del__(self, _warn=warnings.warn): threads = [thread for thread in list(self._threads.values()) - if thread.is_alive()] + if thread.is_alive()] if threads: _warn(f"{self.__class__} has registered but not finished child processes", ResourceWarning, From 6bcf009eb208d60af8f9d364de82e3b3d3d760bd Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 24 Oct 2019 03:20:34 -0400 Subject: [PATCH 4/5] Don't join daemon threads --- Lib/asyncio/unix_events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 18845c7493c2e7..2adae9afbab41f 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1270,7 +1270,7 @@ def close(self): def _join_threads(self): threads = [thread for thread in list(self._threads.values()) - if thread.is_alive()] + if thread.is_alive() and not thread.daemon] for thread in threads: thread.join() From fe2b25619987bd56fb5be667c252d3b612a47006 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 24 Oct 2019 03:25:21 -0400 Subject: [PATCH 5/5] Add docstring for ThreadedChildWatcher._join_threads() --- Lib/asyncio/unix_events.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 2adae9afbab41f..8c0a57482b7a49 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1269,6 +1269,7 @@ def close(self): self._join_threads() def _join_threads(self): + """Internal: Join all non-daemon threads""" threads = [thread for thread in list(self._threads.values()) if thread.is_alive() and not thread.daemon] for thread in threads: