[Return to Bookshelf] [Contents] [Previous Section] [Next Section] [Index] [Help]


cma_once

Calls an initialization routine that can be executed by only one thread, a single time.

Syntax

cma_once(
         init_block,
         init_routine,
         arg);
 


Argument Data Type Access

init_block opaque cma_t_once read init_routine opaque cma_t_init_ read routine arg opaque cma_t_address read


C Binding

#include 

void cma_once ( cma_t_once *init_block, cma_t_init_routine *init_routine, cma_t_address arg);

Arguments

init_block
Address of a record that defines the one-time initialization code. Each one-time initialization routine must have its own unique cma_t_once.
init_routine
Address of a procedure that performs the initialization. This routine is called only once, regardless of the number of times it and its associated init_block are passed to cma_once.
arg
Argument passed to the init_routine.

Description

This routine calls an initialization routine that can be executed by only one thread, a single time. This routine allows you to create your own initialization code that is guaranteed to be run only once, even if called simultaneously by multiple threads.

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.


Note
If you specify an init_ routine that directly or indirectly results in a recursive call to cma_once specifying the same init_block argument, the recursive call will result in a deadlock.

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.

Exceptions

cma_e_badparam

Example

    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
    

    1. Declare the cma_t_once that defines the particular one- time initialization code.

    2. Declare the mutex to be initialized.

    3. Declare the initialization routine that will create the mutex.

    4. 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.



[Return to Bookshelf] [Contents] [Previous Section] [Next Section] [Index] [Help]