If the timeout isn't null, pthread_cond_timedwait does some work to convert the timeout to a timestamp. If this fails (which it can at least in principle) the resulting error path corrupts the state.
With iStatus != 0, it will not set iLocalWaitingThreads, nor will it attempt to take the semaphore, but it will use the uninitialized value of iLocalWaitingThreads to decrement pxCond->iWaitingThreads. The first decrement attempt in prvTestAndDecrement will most likely fail (though it might not) but prvTestAndDecrement will then retry, and thenceforth the waiter count will be permanently off by one.
This was found by gcc correctly reporting that iLocalWaitingThreads is used uninitialized. FYI.
Fix is to return immediately on error if the timing logic fails.
If the timeout isn't null, pthread_cond_timedwait does some work to convert the timeout to a timestamp. If this fails (which it can at least in principle) the resulting error path corrupts the state.
With iStatus != 0, it will not set iLocalWaitingThreads, nor will it attempt to take the semaphore, but it will use the uninitialized value of iLocalWaitingThreads to decrement pxCond->iWaitingThreads. The first decrement attempt in prvTestAndDecrement will most likely fail (though it might not) but prvTestAndDecrement will then retry, and thenceforth the waiter count will be permanently off by one.
This was found by gcc correctly reporting that iLocalWaitingThreads is used uninitialized. FYI.
Fix is to return immediately on error if the timing logic fails.