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

Reply via email to