bpo-23057: add loop self socket as wakeup fd for signals#11135
bpo-23057: add loop self socket as wakeup fd for signals#11135asvetlov merged 12 commits intopython:masterfrom
Conversation
|
A test for making sure that interruption works would be great to have |
|
Looks good! |
| proactor.set_loop(self) | ||
| self._make_self_pipe() | ||
| self_no = self._csock.fileno() | ||
| if isinstance(self_no, int): |
There was a problem hiding this comment.
I'm curious when fileno() doesn't return int?
Especially taking into account that self._csock is created by asyncio itself, it is not a user-provided object.
There was a problem hiding this comment.
I saw this happening when _csock was mocked.
There was a problem hiding this comment.
We can fix all mocks from asyncio test suite and don't care if a third-party library will use mocking incorrectly,
|
Yes, I'll take a look at CI failures during the weekend - looks odd since all tests were passing locally. I'm not sure how important is this use-case and what are general expectations for the internal state of event loop after breaking out of |
|
Selector based loops use the same technique for waking a loop. |
|
Proactor loop does it as well - it schedules reading when self pipe is created.
|
|
Thanks for the explanation. Changing signal handlers is not an option for this particular pull request. I have a feeling that if we change signal handler for one loop implementation -- we should do it for all others. I see a motivation for handling interruption signals differently but the change is a subject for another discussion. The second option can work. |
|
in last update I've wrapped call to
|
|
@asvetlov please let me know if there is anything else that needs to be addressed. |
|
I still recommend removing |
|
will do |
| # and self-reading routine is not hooked up now and needs | ||
| # to be restarted | ||
| if (self._self_reading_future is not None and | ||
| self._self_reading_future.cancelled()): |
There was a problem hiding this comment.
Please replace .cancelled() with .done().
Interruption can occur when the recv() called fut.set_result() but before loop._loop_self_reading() callback executed on the next loop iteration.
| self._self_reading_future = None | ||
| self.call_soon(self._loop_self_reading) | ||
| super().run_forever() | ||
| except KeyboardInterrupt: |
There was a problem hiding this comment.
Replace except with finally.
Canceling self-reading doesn't make harm if run_forever() was stopped by another exception (or just normal execution finishing).
We will re-schedule self-reading again on next run_forever() call.
|
Or even better:
What do you think? |
|
I think looks plausible if we add |
…l self_reading_future afterwards
|
Excellent! |
|
@asvetlov: Please replace |
|
This change broke the AMD64 Windows7 SP1 3.x builder (https://buildbot.python.org/all/#/builders/40). Note that this builder runs as a service so no console is attached. |
|
Seems related but different error on x86 Windows7 3.x (https://buildbot.python.org/all/#/builders/58). Both builders are running on Windows 7, which may make a difference as well. |
|
will take a look |
|
I think #11274 should address the issue.
|
|
Got my hands on Win7 VM, reproduced the issue and verified that it is fixed by #11274 |
When wakeup fd is set - receiving the signal will also write its number to a fd. This in turn will unblock the proactor and allow to process pending signal handler.
Is this approach valid in general and if yes - what is the best way to test changes like this? // cc @asvetlov
https://bugs.python.org/issue23057