NAME
call_once —
dynamic package initialization
SYNOPSIS
#include
<threads.h>
void call_once(once_flag *flag, void (*init_routine)(void)); once_flag flag = ONCE_FLAG_INIT;
DESCRIPTION
[CX] The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2024 defers to the ISO C standard.
The call_once () function
shall use the
once_flag
pointed to by flag to ensure that
init_routine is called exactly once, the first time the
call_once () function is called with that value of
flag. Completion of an effective call to the
call_once () function shall synchronize with all
subsequent calls to the call_once () function with
the same value of flag.
[CX] The call_once ()
function is not a cancellation point. However, if
init_routine is a cancellation point and is canceled, the
effect on flag shall be as if
call_once () was never called.
If the call to init_routine is terminated by a call to longjmp(3) or siglongjmp(3), the behavior is undefined.
The behavior of call_once () is undefined
if flag has automatic storage duration or is not
initialized by ONCE_FLAG_INIT.
The call_once () function shall not be
affected if the calling thread executes a signal handler during the
call.
RETURN VALUE
The call_once () function shall not return
a value.
ERRORS
No errors are defined.
EXAMPLES
None.
APPLICATION USAGE
If init_routine recursively calls
call_once () with the same flag,
the recursive call will not call the specified
init_routine, and thus the specified
init_routine will not complete, and thus the recursive
call to call_once () will not return. Use of
longjmp(3) or siglongjmp(3) within an
init_routine to jump to a point outside of
init_routine prevents init_routine from
returning.
RATIONALE
For dynamic library initialization in a multi-threaded process, if
an initialization flag is used the flag needs to be protected against
modification by multiple threads simultaneously calling into the library.
This can be done by using a statically-initialized mutex. However, the
better solution is to use call_once () or
pthread_once(3) which are designed for exactly this
purpose, for example:
#include <threads.h>
static once_flag random_is_initialized = ONCE_FLAG_INIT;
extern void initialize_random(void);
int random_function()
{
call_once(&random_is_initialized, initialize_random);
...
/* Operations performed after initialization. */
}
The call_once () function is not affected
by signal handlers for the reasons stated in XRAT
B.2.3
Error Numbers.
FUTURE DIRECTIONS
None.
SEE ALSO
XBD V1_chap04(7), <threads.h>
CHANGE HISTORY
First released in Issue 8. Included for alignment with the ISO/IEC 9899:2018 standard.