wait()/alarm() race condition

Mikko Työläjärvi mbsd at pacbell.net
Sun Mar 30 19:23:03 PST 2003


On Sun, 30 Mar 2003, Sean Hamilton wrote:

> Dan Nelson wrote:
> | Just make sure your signal handler has the SA_RESTART flag unset
> | (either via siginterrupt() if the handler was installed with signal(),
> | or directly if the signal was installed with sigaction() ), and the
> | signal will interrupt the wait() call.
>
> Er, I think you've missed my problem. Or I'm not getting your solution.
>
> I'm concerned about this order of events:
>
> - alarm()
> - wait() returns successfully
> - if (alarmed...) [false]
> - SIGALRM is delivered, alarmed = true
> - loop
> - wait() waits indefinitely
>
> This is incredibly unlikely to ever happen, but it's irritating me somewhat
> that the code isn't airtight. Bad design. Surely there is some atomic means
> of setting a timeout on a system call.

My stock solution to this kind of problem is to turn those pesky
signals into I/O and use an old fashioned select() loop to handle
them; create a pipe(2), let signal handlers write one-byte "messages"
(the signal number) into the pipe and then use select() to dequeue the
events (signals) from the pipe.

Select() has a timeout parameter you can play with to your hearts
content, and provided you don't overflow the pipe, no events will
get lost.  You'd have to install a hander for SIGCHLD, of course.

  $.02,
  /Mikko


More information about the freebsd-hackers mailing list