Commit e18adbab authored by Kirill Smelkov's avatar Kirill Smelkov

Nogil signals

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
parent ce507f4e
Pipeline #19469 passed with stage
in 0 seconds