Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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..

like image 841
user3599803 Avatar asked Jun 11 '17 13:06

user3599803


People also ask

What does pause () do in C?

The pause function suspends program execution until a signal arrives whose action is either to execute a handler function, or to terminate the process. If the signal causes a handler function to be executed, then pause returns.

What is signal pause?

signal. pause() Cause the process to sleep until a signal is received; the appropriate handler will then be called. Returns nothing. Availability: Unix.

Does signal () call the signal handler?

signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer- defined function (a "signal handler"). If the signal signum is delivered to the process, then one of the following happens: * If the disposition is set to SIG_IGN, then the signal is ignored.

Which signal is used to pause a process?

When you use SIGSTOP to a process it will pause the process.


2 Answers

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.

like image 139
Ben Steffan Avatar answered Oct 22 '22 14:10

Ben Steffan


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.

like image 37
R.. GitHub STOP HELPING ICE Avatar answered Oct 22 '22 12:10

R.. GitHub STOP HELPING ICE