Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid the interruption of sleep calls due to a signal in Linux?

Tags:

c

linux

signals

I'm using a real time signal in Linux to be notified of the arrival of new data in a serial port. Unfortunately this causes sleep calls to be interrupted when there is signal.

Does anybody know of a way to avoid this behavior?

I tried using a regular signal (SIGUSR1) but I keep getting the same behavior.

like image 784
jassuncao Avatar asked Feb 08 '10 18:02

jassuncao


People also ask

Can a signal handler be interrupted?

Signal handlers can be interrupted by signals, including their own. If a signal is not reset before its handler is called, the handler can interrupt its own execution. A handler that always successfully executes its code despite interrupting itself or being interrupted is async-signal-safe.

What causes interrupted system call?

5.5. 5 Interrupted System Calls This is a consequence of the interaction between multiple threads and the signals that gdb uses to implement breakpoints and other events that stop execution. To handle this problem, your program should check the return value of each system call and react appropriately.

What is Nanosleep in Linux?

nanosleep() suspends the execution of the calling thread until either at least the time specified in *req has elapsed, or the delivery of a signal that triggers the invocation of a handler in the calling thread or that terminates the process.

How do I interrupt Nanosleep?

If you want to interrupt the sleep you simply send a character to the write side of the pipe. This solution provides a much more fine-grained solution and doesn't require global signal handlers and horrible side-effects. It's also susceptible to interruption and requires the same EINTR restart logic as mentioned above.


2 Answers

From the nanosleep manpage:

nanosleep delays the execution of the program for at least the time specified in *req. The function can return earlier if a signal has been delivered to the process. In this case, it returns -1, sets errno to EINTR, and writes the remaining time into the structure pointed to by rem unless rem is NULL. The value of *rem can then be used to call nanosleep again and complete the specified pause.

like image 99
Martijn van den Broek Avatar answered Sep 22 '22 23:09

Martijn van den Broek


You can mask almost all signals (except SIGKILL) using sigprocmask() or signal() calls. The first one will return you the previous mask, which you can recover after sleep(). Some examples are here. If that does not help, please, be more verbose of what signal interrupts your sleep. I think, you can additionally check this condition ("sleep interrupted by signal?") and fall into sleep again.

like image 39
dma_k Avatar answered Sep 24 '22 23:09

dma_k