On Sat, Dec 02, 2017 at 04:38:29AM +0000, Adam D. Ruppe via Digitalmars-d-learn 
wrote:
> On Saturday, 2 December 2017 at 04:28:57 UTC, Wanderer wrote:
> > Thanks! This works. But it seems a little bit suspicions that D's
> > type for handler function has `nothrow` `@nogc` and `@system`. I
> > wonder why is that?
> 
> Signal handlers are ridiculously limited in what they are allowed to
> do.  Really, you should just set a global variable from the handler
> and check it on the outside.

Signal handlers can potentially be invoked while inside a non-reentrant
libc or OS function, so trying to do anything that (indirectly or
otherwise) calls that function will cause havoc to your program.  Also,
while the signal handler is running, some (all?) further signals may be
blocked, meaning that your program might miss an important signal if
your sig handler takes too long to run.  Furthermore, the signal may
have happened in the middle of your own code, so race conditions may
apply (e.g. if you're modifying global data in both).

So yeah, in general the signal handler should do as little as possible,
usually set a flag or something to indicate that a signal has been
received, and let the main program do the actual work of responding to
the signal, outside of signal handler context.

A neat trick I learned years ago is the so-called self-pipe trick, which
is especially useful when your main program has a select/epoll loop.
Basically, you use the Posix pipe() function to create a read/write
pipe, and add the read end to your select/epoll fd set. Then in the
signal handler you write to the write end of the pipe (e.g., write the
signal number) and return. (The write() function is one of the few OS
functions that's safe to call inside a signal handler.)  Now you can do
the "real" signal processing in your select/epoll loop when the read end
of the pipe indicates that it's ready for reads.  This lets you avoid
the above problems with restrictions in signal handler context, and also
integrates nicely into your event loop, so that you can be sure that
you're done with whatever it is your other event loops are doing when
you actually get around to processing the signal.


T

-- 
There's light at the end of the tunnel. It's the oncoming train.

Reply via email to