blocxx
ThreadOnce.hpp
Go to the documentation of this file.
1/*******************************************************************************
2* Copyright (C) 2005, Vintela, Inc. All rights reserved.
3* Copyright (C) 2006, Novell, Inc. All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7*
8* * Redistributions of source code must retain the above copyright notice,
9* this list of conditions and the following disclaimer.
10* * Redistributions in binary form must reproduce the above copyright
11* notice, this list of conditions and the following disclaimer in the
12* documentation and/or other materials provided with the distribution.
13* * Neither the name of
14* Vintela, Inc.,
15* nor Novell, Inc.,
16* nor the names of its contributors or employees may be used to
17* endorse or promote products derived from this software without
18* specific prior written permission.
19*
20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30* POSSIBILITY OF SUCH DAMAGE.
31*******************************************************************************/
32
33
38#ifndef BLOCXX_THREAD_ONCE_HPP_INCLUDE_GUARD_
39#define BLOCXX_THREAD_ONCE_HPP_INCLUDE_GUARD_
40#include "blocxx/BLOCXX_config.h"
41#include "blocxx/Assertion.hpp"
42
43#if defined(BLOCXX_USE_PTHREAD)
44#include <pthread.h>
45#include <csignal> // for sig_atomic_t
46#include <cassert>
48#elif defined(BLOCXX_WIN32)
49#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
50#include <wtypes.h>
51#endif
52
53namespace BLOCXX_NAMESPACE
54{
55
56#ifdef BLOCXX_NCR
57#ifndef PTHREAD_MUTEX_INITIALIZER
58#define PTHREAD_MUTEX_INITIALIZER {NULL, 0, 0}
59#endif
60#endif
61
62#if defined(BLOCXX_USE_PTHREAD)
63
64struct OnceFlag
65{
66 volatile ::sig_atomic_t flag;
68};
69
70#define BLOCXX_ONCE_INIT {0, PTHREAD_MUTEX_INITIALIZER}
71
72#elif defined(BLOCXX_WIN32)
73
74typedef long OnceFlag;
75#define BLOCXX_ONCE_INIT 0
76
77#else
78#error "Port me!"
79#endif
80
85template <typename FuncT>
87
88
89
90#if defined(BLOCXX_USE_PTHREAD)
91
93{
94public:
96 : m_mtx(mtx)
97 {
98#ifdef BLOCXX_NCR //we get coredump without initialization
99 if (m_mtx->field1 == NULL)
100 {
103 assert(ret == 0);
105 assert(ret == 0);
107 }
108#endif
109
110#ifndef NDEBUG
111 int res =
112#endif // Avoid unused variable warnings
114 assert(res == 0);
115 }
117 {
118#ifndef NDEBUG
119 int res =
120#endif // Avoid unused variable warnings
122 assert(res == 0);
123
124#ifdef BLOCXX_NCR
126#endif
127 }
128private:
130};
131
132template <typename FuncT>
133inline void callOnce(OnceFlag& flag, FuncT f)
134{
136 if (flag.flag == 0)
137 {
139 if (flag.flag == 0)
140 {
141 f();
142 flag.flag = 1;
143 }
144 }
145}
146
147#endif
148
149#if defined(BLOCXX_WIN32)
150
151template <typename FuncT>
152inline void callOnce(OnceFlag& flag, FuncT f)
153{
154 // this is the double-checked locking pattern, but with a bit more strength than normally implemented :-)
155 if (InterlockedCompareExchange(&flag, 1, 1) == 0)
156 {
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;
160
163
164 int res = 0;
167
168 if (InterlockedCompareExchange(&flag, 1, 1) == 0)
169 {
170 try
171 {
172 f();
173 }
174 catch (...)
175 {
180 throw;
181 }
183 }
184
189 }
190}
191
192#endif
193
194} // end namespace BLOCXX_NAMESPACE
195
196#endif
197
#define BLOCXX_ASSERT(CON)
BLOCXX_ASSERT works similar to the assert() macro, but instead of calling abort(),...
Definition Assertion.hpp:57
#define F(x, y, z)
Definition MD5.cpp:209
Taken from RFC 1321.
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 ...
bool operator==(const Array< T > &x, const Array< T > &y)
void readWriteMemoryBarrier()
This function is solely for the use of libblocxx threading primitives.