51Degrees Common C/C++  4.1

A shared functionality library that is used by 51Degrees products

threading.h

1 /* *********************************************************************
2  * This Source Code Form is copyright of 51 Degrees Mobile Experts Limited.
3  * Copyright 2019 51 Degrees Mobile Experts Limited, 5 Charlotte Close,
4  * Caversham, Reading, Berkshire, United Kingdom RG4 7BY
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0.
8  *
9  * If a copy of the MPL was not distributed with this file, You can obtain
10  * one at http://mozilla.org/MPL/2.0/.
11  *
12  * This Source Code Form is "Incompatible With Secondary Licenses", as
13  * defined by the Mozilla Public License, v. 2.0.
14  * ********************************************************************* */
15 
26 #ifndef FIFTYONE_DEGREES_THREADING_INCLUDED
27 #define FIFTYONE_DEGREES_THREADING_INCLUDED
28 
29 #include <stdbool.h>
30 
31 #ifdef __cplusplus
32 #define EXTERNAL extern "C"
33 #else
34 #define EXTERNAL
35 #endif
36 
45 
49 #ifdef _MSC_VER
50 #define FIFTYONE_DEGREES_THREAD_ROUTINE LPTHREAD_START_ROUTINE
51 #else
52 typedef void*(*FIFTYONE_DEGREES_THREAD_ROUTINE)(void*);
53 #endif
54 
55 /* Define NDEBUG if needed, to ensure asserts are disabled in release builds */
56 #if !defined(DEBUG) && !defined(_DEBUG) && !defined(NDEBUG)
57 #define NDEBUG
58 #endif
59 
60 #ifdef _MSC_VER
61 #include <windows.h>
62 #include <intrin.h>
63 #pragma intrinsic (_InterlockedIncrement)
64 #pragma intrinsic (_InterlockedDecrement)
65 #else
66 #include <pthread.h>
67 #include <signal.h>
68 #endif
69 #include <assert.h>
70 
79 #ifdef _MSC_VER
80 typedef HANDLE fiftyoneDegreesMutex;
81 #else
82 typedef pthread_mutex_t fiftyoneDegreesMutex;
103 #endif
104 
109 #ifdef _MSC_VER
110 typedef HANDLE fiftyoneDegreesSignal;
111 #else
112 typedef struct fiftyone_degrees_signal_t {
113  volatile bool wait;
114  pthread_cond_t cond;
115  pthread_mutex_t mutex;
117 #endif
118 
129 
140 
149 
157 
161 #ifdef _MSC_VER
162 #define FIFTYONE_DEGREES_THREAD HANDLE
163 #else
164 #define FIFTYONE_DEGREES_THREAD pthread_t
165 #endif
166 
172 #define FIFTYONE_DEGREES_SIGNAL_CREATE(s) s = fiftyoneDegreesSignalCreate()
173 
178 #define FIFTYONE_DEGREES_SIGNAL_CLOSE(s) fiftyoneDegreesSignalClose(s)
179 
184 #define FIFTYONE_DEGREES_SIGNAL_SET(s) fiftyoneDegreesSignalSet(s)
185 
190 #define FIFTYONE_DEGREES_SIGNAL_WAIT(s) fiftyoneDegreesSignalWait(s)
191 
196 #ifdef _MSC_VER
197 #define FIFTYONE_DEGREES_MUTEX_CREATE(m) m = CreateMutex(NULL,FALSE,NULL)
198 #else
199 #define FIFTYONE_DEGREES_MUTEX_CREATE(m) fiftyoneDegreesMutexCreate(&m)
200 #endif
201 
206 #ifdef _MSC_VER
207 #define FIFTYONE_DEGREES_MUTEX_CLOSE(m) if (m != NULL) { CloseHandle(m); }
208 #else
209 #define FIFTYONE_DEGREES_MUTEX_CLOSE(m) fiftyoneDegreesMutexClose(&m)
210 #endif
211 
216 #ifdef _MSC_VER
217 #define FIFTYONE_DEGREES_MUTEX_LOCK(m) WaitForSingleObject(*m, INFINITE)
218 #else
219 #define FIFTYONE_DEGREES_MUTEX_LOCK(m) fiftyoneDegreesMutexLock(m)
220 #endif
221 
226 #ifdef _MSC_VER
227 #define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) ReleaseMutex(*m)
228 #else
229 #define FIFTYONE_DEGREES_MUTEX_UNLOCK(m) fiftyoneDegreesMutexUnlock(m)
230 #endif
231 
237 #ifdef _MSC_VER
238 #define FIFTYONE_DEGREES_MUTEX_VALID(m) (*m != NULL)
239 #else
240 #define FIFTYONE_DEGREES_MUTEX_VALID(m) fiftyoneDegreesMutexValid(m)
241 #endif
242 
250 #ifdef _MSC_VER
251 #define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) t = \
252  (FIFTYONE_DEGREES_THREAD)CreateThread(NULL, 0, m, s, 0, NULL)
253 #else
254 #define FIFTYONE_DEGREES_THREAD_CREATE(t, m, s) pthread_create(&t, NULL, m, s)
255 #endif
256 
262 #ifdef _MSC_VER
263 #define FIFTYONE_DEGREES_THREAD_JOIN(t) WaitForSingleObject(t, INFINITE)
264 #else
265 #define FIFTYONE_DEGREES_THREAD_JOIN(t) pthread_join(t, NULL)
266 #endif
267 
272 #ifdef _MSC_VER
273 #define FIFTYONE_DEGREES_THREAD_CLOSE(t) CloseHandle(t)
274 #else
275 #define FIFTYONE_DEGREES_THREAD_CLOSE(t)
276 #endif
277 
281 #ifdef _MSC_VER
282 #define FIFTYONE_DEGREES_THREAD_EXIT ExitThread(0)
283 #else
284 #define FIFTYONE_DEGREES_THREAD_EXIT pthread_exit(NULL)
285 #endif
286 
292 #ifdef _MSC_VER
293 #define FIFTYONE_DEGREES_INTERLOCK_INC(v) _InterlockedIncrement(v)
294 #else
295 #define FIFTYONE_DEGREES_INTERLOCK_INC(v) (__sync_add_and_fetch(v, 1))
296 #endif
297 
303 #ifdef _MSC_VER
304 #define FIFTYONE_DEGREES_INTERLOCK_DEC(v) _InterlockedDecrement(v)
305 #else
306 #define FIFTYONE_DEGREES_INTERLOCK_DEC(v) (__sync_add_and_fetch(v, -1))
307 #endif
308 
317 #ifdef _MSC_VER
318 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \
319  InterlockedCompareExchange(&d, e, c)
320 #else
321 #define FIFTYONE_DEGREES_INTERLOCK_EXCHANGE(d,e,c) \
322  __sync_val_compare_and_swap(&d,c,e)
323 #endif
324 
329 #endif
EXTERNAL void fiftyoneDegreesMutexUnlock(fiftyoneDegreesMutex *mutex)
Unlocks the mutex passed to the method.
Definition: threading.c:86
EXTERNAL void fiftyoneDegreesMutexCreate(fiftyoneDegreesMutex *mutex)
Initialises the mutex passed to the method.
Definition: threading.c:70
pthread_mutex_t mutex
Mutex for the signal.
Definition: threading.h:115
fiftyoneDegreesSignal * fiftyoneDegreesSignalCreate()
Initialises the signal pointer by setting the condition first followed by the mutex if the condition ...
Definition: threading.c:90
pthread_mutex_t fiftyoneDegreesMutex
MUTEX AND THREADING MACROS.
Definition: threading.h:82
EXTERNAL void fiftyoneDegreesMutexClose(fiftyoneDegreesMutex *mutex)
Closes the mutex passed to the method.
Definition: threading.c:78
pthread_cond_t cond
Condition variable for the signal.
Definition: threading.h:114
EXTERNAL void fiftyoneDegreesMutexLock(fiftyoneDegreesMutex *mutex)
Locks the mutex passed to the method.
Definition: threading.c:82
A signal used to limit the number of items that can be created by the pool.
Definition: threading.h:112
void fiftyoneDegreesSignalWait(fiftyoneDegreesSignal *signal)
Wait for a signal to be set.
Definition: threading.c:118
void fiftyoneDegreesSignalClose(fiftyoneDegreesSignal *signal)
Closes the signal ensuring there is a lock on the signal before destroying the signal.
Definition: threading.c:103
volatile bool wait
Flag indicating if the thread should wait.
Definition: threading.h:113
void fiftyoneDegreesSignalSet(fiftyoneDegreesSignal *signal)
If the signal has not been destroyed then sends a signal to a waiting thread that the signal has been...
Definition: threading.c:110
EXTERNAL bool fiftyoneDegreesThreadingGetIsThreadSafe()
Determines if the methods that should be thread safe have been compiled so they are thread safe.
Definition: threading.c:134