• Kirill Smelkov's avatar
    Nogil signals · e18adbab
    Kirill Smelkov authored
    Provide os/signal package that can be used to setup signal delivery to nogil
    channels. This way for user code signal handling becomes regular handling of a
    signalling channel instead of being something special or limited to only-main
    python thread. The rationale for why we need it is explained below:
    
    There are several problems with regular python's stdlib signal module:
    
    1. Python2 does not call signal handler from under blocked lock.acquire.
       This means that if the main thread is blocked waiting on a semaphore,
       signal delivery will be delayed indefinitely, similarly to e.g. problem
       described in nexedi/nxdtest!14 (comment 147527)
       where raising KeyboardInterrupt is delayed after SIGINT for many,
       potentially unbounded, seconds until ~semaphore wait finishes.
    
       Note that Python3 does not have this problem wrt stdlib locks and
       semaphores, but read below for the next point.
    
    2. all pygolang communication operations (channels send/recv, sync.Mutex,
       sync.RWMutex, sync.Sema, sync.WaitGroup, sync.WorkGroup, ...) run with
       GIL released, but if blocked do not handle EINTR and do not schedule
       python signal handler to run (on main thread).
    
       Even if we could theoretically adjust this behaviour of pygolang at python
       level to match Python3, there are also C++ and pyx/nogil worlds. And we want gil
       and nogil worlds to interoperate (see https://pypi.org/project/pygolang/#cython-nogil-api),
       so that e.g. if completely nogil code happens to run on the main thread,
       signal handling is still possible, even if that signal handling was setup at
       python level.
    
    With signals delivered to nogil channels both nogil world and python
    world can setup signal handlers and to be notified of them irregardles
    of whether main python thread is currently blocked in nogil wait or not.
    
    /reviewed-on nexedi/pygolang!17
    e18adbab
__init__.py 1.19 KB