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.