user3599803
user3599803

Reputation: 7004

pause() signal handler

The pause() function blocks until a signal arrives. Assuming the process got a signal and pause() returned, does the signal handler will be executed before the code that follows the pause() call, or the result is unexpected?

Example:

void sigusr1_handler() 
{
   // .. handler code
}

void main() 
{
   // .. bind handler to SIGUSR1

   pause(); // wait for SIGUSR1
   // some more code
}

Does "some more code" will always be executed after sigusr1_handler() has finished, or there is a race condition? If so, what is the solution?
I cannot think of anything besides busy-waiting, but then the pause won't be needed at all..

Upvotes: 9

Views: 6232

Answers (2)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215259

Signal handlers do not run concurrently; they interrupt the thread that handles them, and the interrupted flow only continues when the signal handler returns.

However, there may be other race conditions associated with your example; with just sparse pseudo-code and not a full explanation of your usage case, it's hard to say. For example a different signal might arrive and interrupt the pause before your signal does, and then your handler could end up running later than you expected.

There are several "right ways" to do this instead:

  • write a single byte to a pipe in the signal handler, and read from it in the main flow of execution.
  • sem_post a semaphore from the signal handler, and sem_wait in the main flow of execution.
  • Use sigwaitinfo or sigtimedwait instead of a signal handler.
  • Still use pause, but in a loop:

    while(!signal_handler_finished) pause();
    

    where signal_handler_finished has type volatile sig_atomic_t, and is set to a nonzero value in the signal handler.

Upvotes: 3

Ben Steffan
Ben Steffan

Reputation: 1125

Citing from the man page for pause(2):

pause() returns only when a signal was caught and the signal-catching function returned. In this case, pause() returns -1, and errno is set to EINTR.

You can be sure that your signal handler runs before some more code.

Upvotes: 10

Related Questions