Hi Franz, Regarding the specific issue with alarm()/SIGALRM - assuming you have control over the parts of the program which use alarm() to implement timers, I would strongly recommend using zloop_timer() instead. And if you're not yet using zloop, I would highly recommend using zloop too! :-)
Steve From: zeromq-dev [mailto:zeromq-dev-boun...@lists.zeromq.org] On Behalf Of Mark Botner Sent: Monday, March 23, 2020 4:24 AM To: ZeroMQ development list Subject: Re: [zeromq-dev] How to handle EINTR especially when using High-Level APIs as CZMQ For Linux signal handling, in main(), before any threads are created, I call sigprocmask() and SIG_BLOCK all signals that I might receive later. Then, I create a dedicated signal handling thread that calls sigwait() with the same set of signals that I blocked with sigprocmask(). The signal handling thread can deal with any received signals and all other threads don't have to process signals at all. Of course gracefully shutting down still requires a bit of planning, but I find that this is easier than dealing with EINTR everywhere. Mark On Sun, Mar 22, 2020 at 7:54 AM Franz Hollerer <f.holle...@gmx.net<mailto:f.holle...@gmx.net>> wrote: Hello, I wonder how to correctly handle EINTR especially when using a high-level API as CZMQ. The ZeroMQ guide states in section "The CZMQ High-Level API": > One thing CZMQ provides is clean interrupt handling. This means that > Ctrl-C will cause any blocking > ZeroMQ call to exit with a return code -1 and errno set to EINTR . The > high-level recv methods will > return NULL in such cases. So, you can cleanly exit a loop like this: > while (true) { > zstr_send (client, "Hello"); > char *reply = zstr_recv (client); > if (!reply) > break; // Interrupted > printf ("Client: %s\n", reply); > free (reply); > sleep (1); > } The example above assumes that the call is interrupted because someone has pressed Ctrl-C. But on an Unix-like operating system there is not only the SIGTERM and SIGINT (Ctrl+C) signal which may interrupt the system call. Also alarm() and interval timers might be implemented using signals. From the alarm() manpage on Debian 10: > alarm() arranges for a SIGALRM signal to be delivered to the calling > process in seconds seconds. To my understanding handling EINTR needs to be done close to system call where it occurs. In most cases it is appropriate to restart the system call. I wonder how to deal with EINTR at a high-level API. As zstr_recv() maps it to NULL there is no way to distinguish EINTR from other errors. And even if it can be distinguished somehow, it might be a bad idea to restart the high-level API function. Leaving the loop as shown above works for SIGTERM and SIGINT. But what if some other part of the program uses interval timers and the call was interrupted by a SIGALARM? Any recommendations? Regards, Franz Hollerer _______________________________________________ zeromq-dev mailing list zeromq-dev@lists.zeromq.org<mailto:zeromq-dev@lists.zeromq.org> https://lists.zeromq.org/mailman/listinfo/zeromq-dev
_______________________________________________ zeromq-dev mailing list zeromq-dev@lists.zeromq.org https://lists.zeromq.org/mailman/listinfo/zeromq-dev