Nathaniel Smith added the comment:

> I'm not sure I understand how `f_func` would help to better handle Control-C 
> in Trio. Nathaniel, could you please elaborate on that?

Sure. The issue is that I need to mark certain frames as "protected" from 
KeyboardInterrupt, in a way that my signal handler can see when walking the 
frame stack, so it can decide whether to raise a KeyboardInterrupt immediately 
or to wait until a safer moment. Right now, this is done by injecting a magic 
local variable into the frame object, so the code is effectively like:

def a_protected_function():
    _trio_keyboard_interrupt_protection_magic_local_ = True
    ... actual function ...

But this has two problems: (1) it's not atomic: a signal could arrive in 
between when the frame is created and when the magic local gets set. (This is 
especially a problem for __(a)exit__ methods -- if bpo-29988 is fixed then it 
will guarantee that __(a)exit__ gets called, but this isn't much help if 
__(a)exit__ can instantly abort without doing any actual cleanup :-).) (2) The 
decorator code for setting this magic local ends up having to special-case 
functions/generators/async functions/async generators, so it's very complex and 
fragile: 
https://github.com/python-trio/trio/blob/1586818fbdd5c3468e15b64816db9257adae49c1/trio/_core/_ki.py#L109-L149
(This is possibly the function that took the most tries to get right in all of 
trio, because there are serious subtleties and interactions with multiple 
CPython bugs.)

I suspect the way I'm currently munging frames at runtime also annoys PyPy's 
JIT.

OTOH if frames had f_func, then instead of having to munge frame.f_locals, I 
could set a magic attribute on the *functions* that are supposed to transition 
between protected/unprotected mode. Then I could delete all that nasty code and 
replace it with something like:

def enable_ki_protection(func):
    func._trio_keyboard_interrupt_protection_enabled = True
    return func

and in addition to being simpler, this would fix the race condition and improve 
performance too. (Note that now this decorator only runs at function definition 
time; I wouldn't have to do any tricky stuff at all during regular execution.)

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue12857>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to