Does a thread own a mutex after pthread_cond_timedwait times out?
condition-variable, multithreading, posix, pthreads
Solution
You are looking at an older issue of POSIX. Issue 7 has this clarified text:
When such timeouts occur, `pthread_cond_timedwait()` shall nonetheless release and re-acquire the mutex referenced by mutex, and may consume a condition signal directed concurrently at the condition variable.
If it didn't reacquire the mutex in this case you'd have to re-acquire it in the calling code anyway so you could re-test the condition after a timeout, because you might have consumed a condition signal. It's only if the condition you're waiting for hasn't occurred and a timeout occurred that you should treat it as the timeout case.
The timeout isn't guarding against the mutex being held for overly long, it's guarding against a condition signal not arriving in a timely manner (generally, the mutex should only be held for short, relatively deterministic periods whereas the condition being waited for might be influenced by external inputs).
Problem
After a thread calls `pthread_cond_timedwait`, and it returns `ETIMEDOUT`, does the thread own the mutex? I would initially think NO, but it appears that we must call `pthread_mutex_unlock` even after `pthread_cond_timedwait` returns `ETIMEDOUT`. The documentation says: Upon successful return, the mutex shall have been locked and shall be owned by the calling thread. So, upon nonsuccessful return (return value != 0), the mutex is NOT owned, I would think. But, if we do not call `pthread_mutex_unlock` after `ETIMEDOUT`, the mutex appears to be in a broken state (ie I cannot get another thread to acquire it, it just stalls). The documentation also hints at this as well, as they always unlock the mutex regardless of the return value of `pthread_cond_timedwait`: ``` (void) pthread_mutex_lock(&t.mn); t.waiters++; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += 5; rc = 0; while (! mypredicate(&t) && rc == 0) rc = pthread_cond_timedwait(&t.cond, &t.mn, &ts); t.waiters--; if (rc == 0) setmystate(&t); (void) pthread_mutex_unlock(&t.mn); ``` So, does the thread ALWAYS acquire the mutex after `pthread_cond_timedwait`? It does not really make sense because the call would have to block more than the specificed time in order to acquire the mutex again.