D766 - A statically initialised lock is made on first use
Status: decided Date: 2026-10-08
known_by: published (FreeBSD libthr,
thr_mutex.c and thr_cond.c)
A mutex word holding PTHREAD_MUTEX_INITIALIZER (0) or
the adaptive initialiser (1) is made the first time it is locked,
try-locked or timed-locked, as libthr's
CHECK_AND_INIT_MUTEX makes it. The type is libthr's
default, error-checking, or a normal lock for the adaptive initialiser.
A destroyed mutex holds libthr's destroyed marker (2) and answers
EINVAL.
A condition-variable word holding
PTHREAD_COND_INITIALIZER (0) is made the first time it is
waited on, signalled or broadcast (CHECK_AND_INIT_COND). A
destroyed one holds the marker (1) and answers EINVAL.
Each kind is made under one lock and re-read under it, so two threads that take the same static lock first make a single lock between them.
Why: a title's own libc.prx guards its
static constructors with static locks. Its
__cxa_guard_acquire and __cxa_guard_release
aborted the title with "failed to acquire mutex" and "failed to
broadcast" when the lock answered a bad handle. il2cpp's collector lock
is static too, and its try-lock spun on the same refusal.
Supersedes: the refusal recorded on
mutex_at ("a statically initialised lock names nothing").
That answer was right not to grant success, but the platform makes the
lock rather than refusing it.