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] [Option Start] 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. [Option End]

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] [Option Start] 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() or siglongjmp(), 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. [Option End]

RETURN VALUE

The call_once() function shall not return a value.

ERRORS

No errors are defined.


The following sections are informative.

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() or siglongjmp() 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() 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

pthread_once

XBD 4.15.2 Memory Synchronization , <threads.h>

CHANGE HISTORY

First released in Issue 8. Included for alignment with the ISO/IEC 9899:2018 standard.

End of informative text.