Unfortunately, signalfd has a very irritating practical issue.
To use it, you need to block the signal you're interested in (using e.g. sigsetmask). However, the set of blocked signals is not reset by exec (blocked signals and signals set to SIG_IGN are preserved, but other signal actions are reset to default). So, if you use signalfd, whenever you spawn a process, it will not receive that signal. And processes tend to misbehave when not receiving signals they expect to.
You can, of course, fix that. You simply need to unblock the signal after forking, but before exec'ing. *IF* you control everything that ever calls fork/exec from your process. In many situations, that is impossible -- programs tend to use all sorts of libraries, some of which spawn processes.
Okay, so, you might say: "Hey, that's what pthread_atfork is for! Just set an child-side after-fork handler to unblock the signal". Well, unfortunately, pthread_atfork doesn't always get called when spawning a child process, so you can't really use it for that.
Three examples of that:
1) For the system() call, POSIX says: "It is unspecified whether the handlers registered with pthread_atfork() are called as part of the creation of the child process." In glibc, they aren't.
2) Regarding posix_spawn, POSIX says: "It is implementation-defined whether the fork handlers are run when posix_spawn() or posix_spawnp() is called." In glibc, they are.
3) The linux-specific clone() system-call does not have atfork handlers called.
So, basically, end result: signalfd is unusable in many circumstances where it'd be really nice to be able to use it -- you're better off just setting a standard signal handler which writes to an fd. Sigh.