Skip to content
This repository has been archived by the owner on Nov 23, 2017. It is now read-only.

Support SIGINT signal on Windows #191

Closed
GoogleCodeExporter opened this issue Apr 10, 2015 · 12 comments
Closed

Support SIGINT signal on Windows #191

GoogleCodeExporter opened this issue Apr 10, 2015 · 12 comments

Comments

@GoogleCodeExporter
Copy link

Currently, it's not possible to stop an event loop on Windows with CTRL+c 
(SIGINT signal). The feature should be implemented in SelectorEventLoop and/or 
ProactorEventLoop.

For SelectorEventLoop:

I tried to call "signal.set_wakeup_fd(self._csock.fileno())" where
self._csock is read end of the "self" pipe of the event loop, used to
wakeup the event loop on call_soon_threadsafe() or signals.

The problem is that set_wakeup_fd() expects a file, whereas
SelectorEventLoop uses a socket pair for the "self" pipe. Using a file
would be an issue with select.select() because it only supports
sockets...

I modified locally set_wakeup_fd() to use send() instead of write()
and accept sockets: it works!


For ProactorEventLoop:

There is an "Event" used by the C signal handler of Python: the event
is set when Python gets a SIGINT signal. The event is now private, but
it might be possible to retrieve it using ctypes or a modification of
Python 3.5.

It should be possible to register to event into the IOCP event loop to
wake up the event loop when the event is set. I didn't try to
implement it.


Until asyncio supports SIGINT on Windows, a workaround is to use a
periodic task to interrupt the event loop every N seconds.

Original issue reported on code.google.com by victor.s...@gmail.com on 16 Jul 2014 at 3:15

@GoogleCodeExporter
Copy link
Author

windows_sig_handler.patch: work-in-progress patch for SelectorEventLoop, it 
requires to patch Python to accept a socket for the wakeup file descriptor.


Original comment by victor.s...@gmail.com on 18 Jul 2014 at 10:59

Attachments:

@GoogleCodeExporter
Copy link
Author

proactor_sigint.py: proof-of-concept for ProactorEventLoop. It uses ctypes to 
get the internal Python "Sigint_Event" Event. FIXME: the event must be reseted 
before we start to wait for it.

Original comment by victor.s...@gmail.com on 18 Jul 2014 at 11:01

Attachments:

@GoogleCodeExporter
Copy link
Author

For select.select(), I just opened a new issue to propose to support sockets 
for select.set_wakeup_fd():
http://bugs.python.org/issue22018

Original comment by victor.s...@gmail.com on 20 Jul 2014 at 7:47

@GoogleCodeExporter
Copy link
Author

For the "# FIXME: reset the event" in proactor_sigint.py, I missed the 
_overlapped.ResetEvent() function.

Original comment by victor.s...@gmail.com on 20 Jul 2014 at 8:16

@GoogleCodeExporter
Copy link
Author

Patch: "Implement signal handlers in the Windows SelectorEventLoop using 
signal.set_wakeup_socket()"
http://codereview.appspot.com/119990043

It requires the new signal.set_wakeup_socket() function, I wrote a patch to add 
it in Python 3.5:
http://bugs.python.org/issue22018

Original comment by victor.s...@gmail.com on 22 Jul 2014 at 3:25

@GoogleCodeExporter
Copy link
Author

test_win_signals.py: script to to test Windows signal. Run the script and type 
CTRL+c, CTRL+Pause or CTRL+Scroll. Lock. The event loop should stop immediatly 
with a message.

Original comment by victor.s...@gmail.com on 22 Jul 2014 at 3:27

Attachments:

@GoogleCodeExporter
Copy link
Author

Patch implementing ProactorEventLoop.add_signal_handler(SIGINT):
http://codereview.appspot.com/119930044

The patch depends on the issue #195, without this fix, remove_signal_handler() 
will crash if you already got the signal.

Only SIGINT is supported currently. The patch uses ctypes to get the privte 
_PyOS_SigintEvent() function to get the private "Sigint_Event" event.

Use attached test_proactor_sigint.py to test the patch.

I don't think that it's possible to handle the signal more than once. The patch 
should be enhanced to handle multiple calls.

Original comment by victor.s...@gmail.com on 22 Jul 2014 at 4:12

Attachments:

@GoogleCodeExporter
Copy link
Author

"Patch implementing ProactorEventLoop.add_signal_handler(SIGINT): (...) Only 
SIGINT is supported currently."

Oh, in fact I don't see why ProactorEventLoop would not use the self-pipe as 
the wakeup fd, as SelectorEventLoop on Windows. So we can support any signal, 
not only SIGINT. It would avoid the need of accessing a private function to get 
a private event object (Sigint_Event).

Original comment by victor.s...@gmail.com on 23 Jul 2014 at 12:52

@GoogleCodeExporter
Copy link
Author

I pushed my patch to support sockets in signal.set_wakeup_fd() on Windows in 
Python 3.5:
http://bugs.python.org/issue22018

I updated my patch for SelectorEventLoop on Windows:
http://codereview.appspot.com/119990043

With the patch, any Windows signal is supported: I tested SIGINT and SIGBREAK. 
SIGINT is tested by unit tests.

Original comment by victor.s...@gmail.com on 30 Jul 2014 at 9:58

@GoogleCodeExporter
Copy link
Author

Well done :)

Original comment by arve.knu...@gmail.com on 31 Jul 2014 at 6:49

@stefanotorresi
Copy link

stefanotorresi commented Aug 30, 2016

I'm not clear whether or not this should be fixed by https://bugs.python.org/issue22018, but I still can reproduce the issue with python 3.5.2

@gvanrossum
Copy link
Member

Can you please open a new issue?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants