Nathaniel Smith wrote:
So what should this async_signals_masked state do when we yield out
from under it?  If it's a thread-local, then the masking state will
"leak" into other async function callstacks (or similar for regular
generators), which is pretty bad. But it can't be just frame-local
data either, because we want the masking state to be inherited by and
subroutines we call from inside the masked block.

That should be easy enough, shouldn't it? When entering a new
frame, copy the mask state from the calling frame.

For example, we could have a flag on a function frame that says
"this frame (and the code in it) should not be interrupted", and then
in the bytecode loop when a signal arrives, walk up the call stack to
see if any of these flags are set before running the Python-level
signal handler.

That would make it impossible to temporarily unmask async
signals in a region where they're masked.

An example of a situation where you might want to do that is
in an implementation of lock.acquire(). If the thread needs to
block while waiting for the lock to become available, you
probably want to allow ctrl-C to interrupt the thread while
it's blocked.

This would make me nervous, because context managers are used for all
kinds of things, and only some of them involve delicate resource
manipulation.

The next step I had in mind was to extend the context manager
protocol so that the context manager can indicate whether it
wants async signals masked, so it would only happen for things
like lock that really need it.

--
Greg

_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to