Thanks Greg for the insight into the problem. The fact that the signal handler runs in the same thread was not something I thought. Also I think it confirms using SIGEV_THREAD for this is the safe approach in this scenario.
Best, Matias On Wed, Jan 13, 2021, at 19:06, Gregory Nutt wrote: > > > I am thinking that there must be some race condition: When the > > condition variable is created the cond->sem value will be set to > > zero. While waiting for cond->sem, it will be set to -1. If you see > > cond->sem equal to zero, my guess would be that the signal was > > received and cond->sem was incremented asychronously by the signal > > delivery logic. But that is only a guess. > > > I know what is going on. There is no race condition. It is normal > behavior for a signal handler: > > * The signal handler runs on the same thread that receives the signal > * In order for the signal handler to run, the thread must be running. > If the thread is blocked, then it must be unblocked so that the > signal handler can run (that is why EINTR is returned under POSIX... > To indicate only that the thread had to be unblocked and awakened to > process a signal). > * If the thread is blocked waiting on a semaphore, then the semaphore > count must be incremented in order to unblock the thread. > * This must happen BEFORE the signal handler runs. > > So there is no race condition, instead there is a simple ordering issue > The sequence above should be modified like: > > * When the condition variable is created the cond->sem value will be > set to zero. > * While waiting for cond->sem, the value will be decremented to -1 > * When a signal is received, the thread will be awakened be > incremented back to zero. > * THEN the thread will run and signal handler will be invoked with the > cond->sem value ALWAYS equal to zero. > > So it is perfectly normal behavior that the cond->sem count is zero in > this case. It just indicates that the thread is running. So, no, I was > wrong. It is not possible to use pthread_cond_signal() form a thread to > wake itself up BECAUSE it already had to be awakened in order for the > signal handler to run. > > When the signal handler returns, pthread_cond_wait() will run inside of > nxsem_wait_interruptible() and it will correctly ignore the EINTR error > and call nxsem_wait() again. > > > >