38#ifndef BLOCXX_THREAD_ONCE_HPP_INCLUDE_GUARD_
39#define BLOCXX_THREAD_ONCE_HPP_INCLUDE_GUARD_
40#include "blocxx/BLOCXX_config.h"
43#if defined(BLOCXX_USE_PTHREAD)
48#elif defined(BLOCXX_WIN32)
49#define WIN32_LEAN_AND_MEAN
57#ifndef PTHREAD_MUTEX_INITIALIZER
58#define PTHREAD_MUTEX_INITIALIZER {NULL, 0, 0}
62#if defined(BLOCXX_USE_PTHREAD)
66 volatile ::sig_atomic_t flag;
67 ::pthread_mutex_t mtx;
70#define BLOCXX_ONCE_INIT {0, PTHREAD_MUTEX_INITIALIZER}
72#elif defined(BLOCXX_WIN32)
75#define BLOCXX_ONCE_INIT 0
85template <
typename FuncT>
86void BLOCXX_COMMON_API
callOnce(OnceFlag& flag, FuncT
F);
90#if defined(BLOCXX_USE_PTHREAD)
92class CallOnce_pthread_MutexLock
95 CallOnce_pthread_MutexLock(::pthread_mutex_t* mtx)
99 if (m_mtx->field1 == NULL)
101 pthread_mutexattr_t attr;
102 int ret = pthread_mutexattr_create(&attr);
104 ret = pthread_mutex_init(m_mtx, attr);
106 pthread_mutexattr_delete(&attr);
113 pthread_mutex_lock(m_mtx);
116 ~CallOnce_pthread_MutexLock()
121 pthread_mutex_unlock(m_mtx);
125 pthread_mutex_destroy(m_mtx);
129 ::pthread_mutex_t* m_mtx;
132template <
typename FuncT>
133inline void callOnce(OnceFlag& flag, FuncT f)
138 CallOnce_pthread_MutexLock lock(&flag.mtx);
149#if defined(BLOCXX_WIN32)
151template <
typename FuncT>
152inline void callOnce(OnceFlag& flag, FuncT f)
155 if (InterlockedCompareExchange(&flag, 1, 1) == 0)
157 wchar_t mutexName[MAX_PATH];
158 _snwprintf(mutexName, MAX_PATH, L
"%X-%p-587ccea9-c95a-4e81-ac51-ab0ddc6cef63", GetCurrentProcessId(), &flag);
159 mutexName[MAX_PATH - 1] = 0;
161 HANDLE mutex = CreateMutexW(NULL, FALSE, mutexName);
165 res = WaitForSingleObject(mutex, INFINITE);
168 if (InterlockedCompareExchange(&flag, 1, 1) == 0)
176 res = ReleaseMutex(mutex);
178 res = CloseHandle(mutex);
182 InterlockedExchange(&flag, 1);
185 res = ReleaseMutex(mutex);
187 res = CloseHandle(mutex);
#define BLOCXX_ASSERT(CON)
BLOCXX_ASSERT works similar to the assert() macro, but instead of calling abort(),...
void BLOCXX_COMMON_API callOnce(OnceFlag &flag, FuncT F)
The first time callOnce is called with a given onceFlag argument, it calls func with no argument and ...
void readWriteMemoryBarrier()
This function is solely for the use of libblocxx threading primitives.