From 62236fbf61d8916844414b53f69a048043cea998 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 25 Aug 2019 18:02:39 +0300 Subject: [PATCH 1/4] Restore running proactor event loop from non-main thread --- Lib/asyncio/proactor_events.py | 5 ++++- Lib/test/test_asyncio/test_windows_events.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 9b8ae064a8926b..617acf244493a7 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -11,6 +11,7 @@ import socket import warnings import signal +import threading import collections from . import base_events @@ -627,7 +628,9 @@ def __init__(self, proactor): proactor.set_loop(self) self._make_self_pipe() self_no = self._csock.fileno() - signal.set_wakeup_fd(self_no) + if threading.current_thread() is threading.main_thread(): + # wakeup fd can be installed from main thread only + signal.set_wakeup_fd(self_no) def _make_socket_transport(self, sock, protocol, waiter=None, extra=None, server=None): diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 64543268b1efb3..d0ba19391fa080 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -59,6 +59,25 @@ def SIGINT_after_delay(): thread.join() +class ProactorMultithreading(test_utils.TestCase): + def test_run_from_nonmain_thread(self): + finished = False + + async def coro(): + await asyncio.sleep(0) + + def func(): + nonlocal finished + loop = asyncio.new_event_loop() + loop.run_until_complete(coro()) + finished = True + + thread = threading.Thread(target=func) + thread.start() + thread.join() + self.assertTrue(finished) + + class ProactorTests(test_utils.TestCase): def setUp(self): From 7dc511562100c918b562b454352549cdeb65c8ae Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 25 Aug 2019 18:07:57 +0300 Subject: [PATCH 2/4] Add news --- .../NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst diff --git a/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst b/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst new file mode 100644 index 00000000000000..144c3a6e83386c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst @@ -0,0 +1 @@ +Restore instantiation Windows IOCP event loop from non-main thread. From e5b2ce65c73830fee8b1cbb0cb68f9e4a90ab4f9 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 26 Aug 2019 12:32:16 +0300 Subject: [PATCH 3/4] Update Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst Co-Authored-By: Kyle Stanley --- .../next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst b/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst index 144c3a6e83386c..785b06b6482c3b 100644 --- a/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst +++ b/Misc/NEWS.d/next/Library/2019-08-25-18-07-48.bpo-34679.HECzL7.rst @@ -1 +1 @@ -Restore instantiation Windows IOCP event loop from non-main thread. +Restores instantiation of Windows IOCP event loops from the non-main thread. From 9b5e06789817122ecc36266fed67e4dc64ca17a7 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 26 Aug 2019 12:32:30 +0300 Subject: [PATCH 4/4] Update Lib/asyncio/proactor_events.py Co-Authored-By: Kyle Stanley --- Lib/asyncio/proactor_events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 617acf244493a7..229f56e6bb9e29 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -629,7 +629,7 @@ def __init__(self, proactor): self._make_self_pipe() self_no = self._csock.fileno() if threading.current_thread() is threading.main_thread(): - # wakeup fd can be installed from main thread only + # wakeup fd can only be installed to a file descriptor from the main thread signal.set_wakeup_fd(self_no) def _make_socket_transport(self, sock, protocol, waiter=None,