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