Quote:
Originally Posted by
_thomas
You say I can only sem_post() inside a signal handler and only sem_wait() inside a threads?
You can only post inside a signal handler, but you can both post and wait inside threads.
Quote:
I have semaphores implemented on many places inside thread. What if one of my variable is changed more than once in a second ? - my signal handler goes on every second. Thread will have to wait after one variable change for a signal handler to release semaphore to continue processing.
It's possible to make a signal-safe queue to put your requests in so your threads can grab them at their leisure. It will need one semaphore, for the interrupt handler, and one mutex, for threads, and two integers: write postion and read position. Both start at zero.
When a signal happens:
- Mask other interrupts.
- Add the new event/data/whatever to the array.
- Increment the write position. Wrap to zero if beyond the array.
- sem_post.
- Unmask other interrupts.
Threads will read from the list, by:
- Lock the mutex
- Save a copy of the read index
- Increment the read index, wrap to zero if beyond the array
- Unlock the mutex
- sem_wait()
- Read data from the saved index of the array
I originally put sem_wait first, but realized you could let the threads save positions in advance.
If signals happen faster than the threads can handle, the semaphore will keep track(it can count higher than one, it's not a mutex) and not block until they are all handled.
If signals happen way too fast for threads to handle, it's possible for the queue to overflow. Without a safe sem_getvalue this is hard to check for. If you're using gcc, you might try the gcc atomic operations extensions to get the read-index in a safe manner. (For that matter, they might let you dispense with the mutex entirely and grab-increment the read index atomically instead.)
Quote:
I'm also not sure if I need to check return value from sem_wait() and sem_post(). I have set SA_RESTART flag so if function call is interrupted by signal, function will be restarted after signal handler is finished.
If these functions weren't failing somewhere, why are you deadlocking?
Always check the return value.