Try the never-finish branch. In multiproc.nim, if I move the hasPendingOpertions()/poll() loop ahead of the finishParent() loop, then it hangs. As it is, it croaks on an unregistered file-descriptor.
I have also filed this Issue, because I wish I could simply throw away the existing global PDispatcher and start over. (Thanks for commenting, dom.)
(By the way, when I get this working and finish it, I plan to submit it to Nimble. It will be a constrained but very convenient Nim version of the Python multiprocessing library. But let's discuss the API in a separate thread later. We might eventually integrate this with @cheatfate's useful asynctools library.)
I've pushed code to close all unused fds in each new fork, and to end communication gracefully. I do not understand how the failing fds are known to select.
I think this is a bug in a Nim library. But if no-one can help me figure this out, I'll try switching from pipes to sockets (maybe next weekend).
I had a small bug in my own code closing fds, but there is still some state mysteriously held by the global PDispatcher. If I deregister everything properly, and close all the relevant file-descriptors, there is still a problem with new "forks". I solved the problem completely by adding a setGlobalDispatcher() function to asyncdispatch. See https://github.com/nim-lang/Nim/pull/5782
That is a very important addition to the standard library. Without it, we really cannot call posix.fork() at all after using any async calls.