Calls an initialization routine that can be executed by only one thread, a single time.
cma_once( init_block, init_routine, arg);
Argument Data Type Accessinit_block opaque cma_t_once read init_routine opaque cma_t_init_ read routine arg opaque cma_t_address read
#includevoid cma_once ( cma_t_once *init_block, cma_t_init_routine *init_routine, cma_t_address arg);
For example, a mutex or a per-thread context key must be created exactly once. Calling cma_once prevents the problem that occurs when the code that creates a mutex or per-thread context can be called by multiple threads. Without this routine, the execution must be serialized so that only one thread performs the initialization. Other threads that reach the same point in the code would be delayed until the first thread is finished.
This routine initializes the control record if it has not already been initialized, and then determines if the client one-time initialization routine has already executed once. If it has not executed, then this routine calls the initialization routine specified in init_routine. If the client one-time initialization code has already executed once, then this routine returns.
Because the init_routine accepts an argument (arg), a single initialization routine can be used to initialize any number of objects. For example, an initialization routine that creates a global mutex might take the address of a cma_t_mutex variable, which receives the handle of a new mutex. Note that you cannot make every call to the initialization routine using the same control block; it would only be called once. Effectively, each value of arg must be associated with its own control block.
The init_block must be declared static (for example, either extern or static in the C language), and it must be initialized at compile time. In the C language, using cma.h, initialize an init_block using the cma_once_init macro. In other languages, you must initialize a cma_t_once block to a value of three integer zeros. In C, that corresponds to the following:
static cma_t_once block = {0,0,0};
The result of this routine is unpredictable and the cma_e_badparam exception is raised if the init_block is not a properly initialized one-time initialization block.
The following C code segment declares a one-time initialization section that creates a mutex for later use:
#include <CMA.H> static cma_t_once make_my_mutex = cma_once_init; 1 static cma_t_mutex my_mutex; 2 . . . void initialize_mutex (cma_t_address_arg) { 3 cma_mutex_create (&my_mutex, &cma_c_null); } . . . cma_once (&make_my_mutex, initialize mutex, 0); 4
Declare the cma_t_once that defines the particular one- time initialization code.
Declare the mutex to be initialized.
Declare the initialization routine that will create the mutex.
Call cma_once with the initialization control block and routine. If no thread has already executed the initialization routine, it will be called. Otherwise, cma_once returns.