On Solaris, usleep is not thread-safe and will introduce a race
condition when used in a multithreaded environment. This manifests as
SIGALRM signals escaping from its internal call to sigsuspend. If a
signal is missing a handler, the process dies upon receiving it,
crashing.
The Solaris libc code does something rougly equivalent to this:
PreserveSignalHandlers(...);
/* Effectively NOPs out SIGALRM */
DisableSIGALRM(...);
SetTimer(...);
/* Suspends the thread until it receives a SIGALRM signal. When it
receives this signal, it both wakes up *and* receives the
signal. In this case we don't want to do anything but wake up,
so the SIGALRM handler is a NOP.
*/
sigsuspend(...);
RestoreSignalHandlers(...);
return;
The consequences of this code in a multithreaded context is that if
two sleeps are in progress at the same time, one will necessarily
finish before the other, *restore the non-existant handlers*, and go
on doing its thing. When the other sleep finishes, it won't have a NOP
handler to call when waking up, a handler is searched for, none is
found, and thus we crash.