nlib
misc/threading/callonce/callonce.cpp

Sample of nlib_once. Corresponds to pthread_once of pthread.

nlib_once is used to make initialization code run only once. All threads started in the sample attempt to call OnceFunc via nlib_once, but only the first thread actually runs it.

Other threads spin and wait while nlib_onceflag is running, and run the process nlib_once after it ends. This guarantees that OnceFunc is called only once after running nlib_once.

using ::nlib_ns::threading::Thread;
const int NUM_THREAD = 8;
Thread g_Th[NUM_THREAD];
// Initializes statically to avoid race condition.
// g_OnceFlag will be changed by nlib_once atomically.
void OnceFunc() {
// OnceFunc called only once
nlib_printf("OnceFunc start\n");
nlib_printf("OnceFunc end\n");
}
void ThreadFunc() {
nlib_printf("Thread #%d: start\n", th);
// executes OnceFunc if not executed.
// does nothing if OnceFunc already executed
// spins and waits if OnceFunc is executing
nlib_once(&g_OnceFlag, OnceFunc);
// nlib_once confirms 'OnceFunc' is executed only once at this point.
nlib_printf("Thread #%d: end\n", th);
}
bool CallOnceDemo() {
nlib_printf("%d threads tries to execute 'OnceFunc'\n", NUM_THREAD);
nlib_printf("nlib_once executes 'OnceFunc' only once\n\n");
int i;
for (i = 0; i < NUM_THREAD; ++i) {
g_Th[i].Start(ThreadFunc);
}
for (i = 0; i < NUM_THREAD; ++i) {
g_Th[i].Join();
}
ThreadFunc();
return true;
}
static bool SampleMain(int, char**) { return CallOnceDemo(); }
NLIB_MAINFUNC