aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/asyncio/selector_events.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-07-17 22:43:40 +0200
committerVictor Stinner <victor.stinner@gmail.com>2014-07-17 22:43:40 +0200
commitfe5649c7b7bf52147480d6b1124a3d8e3597aee3 (patch)
tree75eddcb18e9c7f4facecbb38732a6678dcad990d /Lib/asyncio/selector_events.py
parentddc8c8db1cd50d3b86cffbb1070ab32e3a14bbae (diff)
downloadcpython-fe5649c7b7bf52147480d6b1124a3d8e3597aee3.tar.gz
cpython-fe5649c7b7bf52147480d6b1124a3d8e3597aee3.zip
Python issue #21645, Tulip issue 192: Rewrite signal handling
Since Python 3.3, the C signal handler writes the signal number into the wakeup file descriptor and then schedules the Python call using Py_AddPendingCall(). asyncio uses the wakeup file descriptor to wake up the event loop, and relies on Py_AddPendingCall() to schedule the final callback with call_soon(). If the C signal handler is called in a thread different than the thread of the event loop, the loop is awaken but Py_AddPendingCall() was not called yet. In this case, the event loop has nothing to do and go to sleep again. Py_AddPendingCall() is called while the event loop is sleeping again and so the final callback is not scheduled immediatly. This patch changes how asyncio handles signals. Instead of relying on Py_AddPendingCall() and the wakeup file descriptor, asyncio now only relies on the wakeup file descriptor. asyncio reads signal numbers from the wakeup file descriptor to call its signal handler.
Diffstat (limited to 'Lib/asyncio/selector_events.py')
-rw-r--r--Lib/asyncio/selector_events.py6
1 files changed, 5 insertions, 1 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index d79c0801b24..cd1a75aa78e 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -94,12 +94,16 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
self._internal_fds += 1
self.add_reader(self._ssock.fileno(), self._read_from_self)
+ def _process_self_data(self, data):
+ pass
+
def _read_from_self(self):
while True:
try:
data = self._ssock.recv(4096)
if not data:
break
+ self._process_self_data(data)
except InterruptedError:
continue
except BlockingIOError:
@@ -114,7 +118,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
csock = self._csock
if csock is not None:
try:
- csock.send(b'x')
+ csock.send(b'\0')
except OSError:
pass