The unfortunate terseness of the original "self-pipe trick" description makes the solution to this difficult to see. As far as I've figured out there are two things to notice:
1) You're supposed to set the pipe to be non-blocking. Presumably you also then don't check the return code of the write(2) call in the signal handler. While this solves the case of a signal handler blocking forever, it does mean you might have dropped writes that correspond to signal receptions. That leads us to:
2) The self-pipe trick specifically calls out handling SIGCHLD (probably because it's one signal that you don't want to ignore!) But given the chances of dropping a byte as described in 1) and the fact that SIGCHLD and fork are explicitly called out, I can only assume that the lesson here is: only have one pipe per signal you intend to handle. Since multiple signals sent to a process may result in a single signal being delivered, your real signal handling code (the stuff that's watching the other end of the pipe) already has to deal with this situation.
As for Capsicum, I can't wait til they implement pdwait(2)! Until then, at least pdfork(2) ensures that the parent process' death kills the child process...