C11’s thread interface was not very clear on failure conditions that some functions might encounter. It was not clear that wait functions for conditional variables (cnd_t
) and tentative locking of mutexes (mtx_t
) may fail spuriously, that is with not apparent reason for the caller. By lack of such a specification, it was not clear how C11 threads could be realized by POSIX threads, e.g.
Allowing spurious wakeups is particularly important for the wait functions, because it makes implementing the cnd_t
type much easier, in particular for the special case that the caller of cnd_signal
or cnd_broadcast
does not hold the lock on the corresponding mutex. On the other hand, from an application point of view this does not change much. Even without spurious wakeups, a thread that called `cnd_wait
`, e.g, must in any case check the real condition they are interested in.
These considerations lead to changes for three functions, cnd_timedwait
, cnd_wait
, and mtx_trylock
.
Section 7.26.3.5 p2 of C17 now reads (emphasis represents changed text):
The
cnd_timedwait
atomically unlocks the mutex pointed to bymtx
and blocks until the condition variable pointed to bycond
is signaled by a call tocnd_signal
or tocnd_broadcast
, or until after theTIME_UTC
-based calendar time pointed to byts
, or until it is unblocked due to an unspecified reason. When the calling thread becomes unblocked it locks the variable pointed to bymtx
before it returns. Thecnd_timedwait
requires that the mutex pointed to bymtx
be locked by the calling thread.
Similar for 7.26.3.6 p2:
The
cnd_wait
atomically unlocks the mutex pointed to bymtx
and blocks until the condition variable pointed to bycond
is signaled by a call tocnd_signal
or tocnd_broadcast
, or until it is unblocked due to an unspecified reason. When the calling thread becomes unblocked it locks the mutex pointed to bymtx
before it returns. Thecnd_wait
requires that the mutex pointed to bymtx
be locked by the calling thread.
Finally, a phrase has been added to the end of 7.26.4.5 p3:
mtx_trylock
may spuriously fail to lock an unused resource, in
which case it returnsthrd_busy
.