Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Race condition in C signal handlers puzzle

I need to know how to avoid a race condition when handling signals in C. Each time my program receives a signal, I want it to alter a (global) linked list. It is vitally important that I not miss a signal, and equally important that the global linked list I'm modifying not be changed while the handler is executing.

The problem is, if I receive a signal, and start the handler, but am then interrupted by another signal. This (as I understand it) triggers a new execution of the signal handler, which will operate on the same global dataset - not permissible!

I can't use a lock, because if the first handler call is interrupted, it will naturally never free the lock for the interrupting handler to pick up. So, how do I do it? Any idea?

like image 204
Benubird Avatar asked Nov 02 '10 11:11

Benubird


2 Answers

If you have the luck to be working in a multi-threaded environment, one of the best ways is to have the global linked list controlled exclusively by a separate thread. Interrupts would enqueue requests to this thread (something that would be executed very quickly, say, by simply passing a pointer), and then the thread would procedurally go through each request and modify the linked list. This allows lockless execution.

Of course, you have to rely on your OS's message passing junk, so that may not be an option.

like image 120
Nate Avatar answered Oct 11 '22 22:10

Nate


You can mask signals while executing signal handler - check sa_mask field of struct sigaction you pass to sigaction() syscall.

like image 31
qrdl Avatar answered Oct 11 '22 22:10

qrdl