Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bsls_bslonce
[Package bsls]

Provide BSL a thread-safe way to execute code once per process. More...

Namespaces

namespace  bsls

Detailed Description

Outline
Purpose:
Provide BSL a thread-safe way to execute code once per process.
Classes:
bsls::BslOnce statically initializable gate-keeper for a once-block
bsls::BslOnceGuard guard for safely using bsls::BslOnce
See also:
Description:
This component provides a pair of classes, bsls::BslOnce and bsls::BslOnceGuard, which give the caller a way to run a block of code exactly once within the current process, particularly in the presence of multiple threads. The typical purpose of this one-time execution is the initialization of a singleton on first use.
[!WARNING!] Clients outside of bsl should not use this component. Because of its location in the hierarchy, this component guards critical sections using a spin-lock. Equivalent components that are more robust and efficient will be provided at a higher level (see bcemt_once).
A bsls::BslOnce object can be statically initialized using the BSLS_BSLONCE_INITIALIZER macro.
Usage:
This section illustrates intended use of this component.
Example 1: Using bsls::BslOnce to Perform a Singleton Initialization:
The following example demonstrates using bsls::BslOnce to initialize a singleton object.
First we declare a struct, MySingleton, whose definition is elided:
  struct MySingleton {

    // PUBLIC DATA
    int d_exampleData;

    // ...
  };
Notice that the data members are public because we want to avoid dynamic runtime initialize (i.e., initialization at run-time before the start of main) when an object of this type is declared in a static context.
Now we implement a function getSingleton that returns a singleton object. getSingleton uses BslOnce to ensure the singleton is initialized only once, and that the singleton is initialized before the function returns:
  MySingleton *getSingleton()
      // Return a reference to a modifiable singleton object.
  {
     static MySingleton singleton = { 0 };
     static BslOnce     once      = BSLS_BSLONCE_INITIALIZER;

     BslOnceGuard onceGuard;
     if (onceGuard.enter(&once)) {
       // Initialize 'singleton'.  Note that this code is executed exactly
       // once.

     }
     return &singleton;
  }
Notice that BslOnce must be initialized to BSLS_BSLONCE_INITIALIZER, and that singleton is a function scoped static variable to avoid allocating it on the heap (which might be reported as leaked memory).