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 // Exclude rarely-used stuff from Windows headers
53 namespace BLOCXX_NAMESPACE
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)
74 typedef long OnceFlag;
75 #define BLOCXX_ONCE_INIT 0
85 template <
typename FuncT>
86 void BLOCXX_COMMON_API
callOnce(OnceFlag& flag, FuncT
F);
90 #if defined(BLOCXX_USE_PTHREAD)
92 class CallOnce_pthread_MutexLock
95 CallOnce_pthread_MutexLock(::pthread_mutex_t* mtx)
98 #ifdef BLOCXX_NCR //we get coredump without initialization
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);
112 #endif // Avoid unused variable warnings
113 pthread_mutex_lock(m_mtx);
116 ~CallOnce_pthread_MutexLock()
120 #endif // Avoid unused variable warnings
121 pthread_mutex_unlock(m_mtx);
125 pthread_mutex_destroy(m_mtx);
129 ::pthread_mutex_t* m_mtx;
132 template <
typename FuncT>
133 inline void callOnce(OnceFlag& flag, FuncT f)
138 CallOnce_pthread_MutexLock lock(&flag.mtx);
149 #if defined(BLOCXX_WIN32)
151 template <
typename FuncT>
152 inline 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);