[nanomsg] On pthread_atfork(), and fork()-safe implementation

  • From: "Garrett D'Amore" <garrett@xxxxxxxxxx>
  • To: "nanomsg@xxxxxxxxxxxxx" <nanomsg@xxxxxxxxxxxxx>
  • Date: Mon, 12 Dec 2016 10:31:07 -0800

The following conversation relates to using fork() with nanomsg (or future
rewrites), where you do *not* immediately call exec().  Using fork() and
then immediately calling exec() is fine, and will continue to work as it
always.

But some people want to use fork() to spawn children, e.g. a child worker
process, that communicates back to the parent somehow.   This is never
going to work.

I’ve been doing a bit more research into pthread_atfork() as part of an
attempt to make my new nng library properly fork()-safe.  I’ve more or less
given up though.

The reason for this is that even the OpenGroup has given up — see
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html
— and especially the RATIONALE section, for the logic behind this.  They
have even indicated plans to deprecate the pthread_atfork() API altogether.

Essentially, it isn’t possible to make a version of the library fork() safe
as it would be necessary to free resources, do locks, etc. — i.e. all those
Async-Signal-Unsafe calls.

So, for libnng, and possibly in the future for libnanomsg, I will be
changing the API so that if you attempt to callback into the library after
fork(), it will actually panic the process.

I probably will also arrange for pthread_atfork() to be called to close any
file descriptors that were not marked close-on-exec…

Stay tuned for more details.

 - Garrett

Other related posts: