call_once (3) - glibc
Split from the chapter glibc: Threads into the per-function layout; see the method page and the glibc ledger for coverage status.
| Field | Value |
|---|---|
| Header | threads.h |
| Standards | C11 section 7.26 (ISO C threads); C23 also exposes the flag type from stdlib.h, C only |
| Exported | call_once@@GLIBC_2.34 plus compat call_once@GLIBC_2.28 (nm, host glibc 2.41) |
| Thread-safety | MT-Safe (manual safety note, Call Once node) |
| Ledger ID | GLIBC-call_once |
Declaration and gates
#include <threads.h>
typedef __once_flag once_flag; /* threads.h:61 */
#define ONCE_FLAG_INIT __ONCE_FLAG_INIT /* threads.h:62 */
void call_once(once_flag *flag, void (*func)(void)); /* threads.h:175 */
No feature-test gate: threads.h declares call_once and the flag type in
every compilation mode. The manual notes that as of C23 once_flag and
ONCE_FLAG_INIT are also defined in stdlib.h, but only for C, not C++
(threads.texi, Call Once).
Semantics
call_once(flag, func) invokes func exactly once, even if call_once is
invoked from several threads with the same flag. The completion of func
synchronizes-with all previous and subsequent calls to call_once with that
flag, so every caller observes the effects of the one execution (manual,
Call Once). flag must be initialized to ONCE_FLAG_INIT before first
use. The function returns void and reports no errors: a caller cannot
distinguish whether it ran func itself or another thread already did,
and a func that fails cannot trigger a retry.
Gotchas and portability
- The POSIX twin is
pthread_oncewith aPTHREAD_ONCE_INITcontrol, documented in pthread_once; the manual’s ISO C section recommendspthread.hAPIs for GNU systems in general. - Exactly-once is per
flagobject; two distinct flags give two runs. - musl 1.2.5:
call_onceis a real function (musl src/thread/call_once.c) andONCE_FLAG_INITis0(musl include/threads.h:41).
References
- glibc manual:
threads.texi, node Call Once - header:
/usr/include/threads.hlines 61-62, 175 - symbols:
nm -D --with-symbol-versions libc.so.6