Self-pipe trick (and failings)
Self-pipe trick (and failings)
Posted Mar 30, 2006 22:13 UTC (Thu) by mkerrisk (subscriber, #1978)In reply to: Self-pipe trick (and failings) by jreiser
Parent article: The new pselect() system call
John,
The fourth paragraph of the article begins, "The traditional solution to this problem is the so-called self-pipe trick ...". That paragraph alleges non-obvious defects in such a trick. What is your response?
I'm not sure if you are asking this question of me (author of article) or "mtk77" (who your article seems to reply to). Anyway, I don't allege any defects in the self-pipe trick; all I say is that it requires quite a bit of code to do things right:
- We create a pipe, and use fcntl(F_SETFL) to mark both ends non-blocking (O_NONBLOCK).
- We include the read end of the pipe in the readfds set given to select().
- When the signal handler is called, it writes a byte to the pipe. By making the write end of the pipe non-blocking, we avoid the possibility of blocking in the signal handler if signals are delivered so rapidly that the pipe fills up. (If we fail to write a byte to the pipe because it is full, that doesn't matter: the presence of the existing bytes already informs us that the signal has been delivered.)
-
We place the select() call in a loop and restart it if interrupted by a signal:
while ((ready = select(nfds, &readfds, NULL, NULL, NULL)) == -1 & errno == EINTR) continue;
- After the select() we can determine if the signal arrived by checking whether the read end of the pipe is among the descriptors returned in readfds.
- We read all of the bytes from the pipe (so that we can know when new signals occur), and take whatever action is needed in response to the signal.
Posted Mar 31, 2006 1:21 UTC (Fri)
by dougm (guest, #4615)
[Link] (1 responses)
Posted Mar 31, 2006 3:41 UTC (Fri)
by mkerrisk (subscriber, #1978)
[Link]
Posted Mar 31, 2006 13:43 UTC (Fri)
by clugstj (subscriber, #4020)
[Link] (1 responses)
It is not a better solution just because it takes less code (in user space).
Posted Apr 6, 2006 10:09 UTC (Thu)
by renox (guest, #23785)
[Link]
Well does glibc includes it?
Whereas kernel implementation is really unique, so it is really better.
That said I find quite awful that glibc would implement pselect leaving the unsuspecting developer vulnerable to the race condition, it should be either implemented in the kernel or not at all (unless the library find a way to close the race condition of course).
Just a nit: I think you want '&&' in the while condition, not '&'.Self-pipe trick (and failings)
Just a nit: I think you want '&&' in the while condition, not '&'.
Self-pipe trick (and failings)
Doh! Thanks, yes.
Yes, it takes some code, but it only needs to be written and debugged once. Then tuck it into you comm library behind a simple interface and forget about the gory details. This is a problem that can be solved completely in user space. Adding a new system call to handle it is adding complexity to the kernel for no good reason.Self-pipe trick (and failings)
> Yes, it takes some code, but it only needs to be written and debugged once.Self-pipe trick (and failings)
No because the self-pipe trick cannot really be put into a library: it play tricks with signals, pipes which could have impact in your code, so each userspace program which need it must reimplement it, I'd hardly call this 'once'.
Plus it is conforming to POSIX standard, even better!