C Standard Library Extensions
1.3.1
cext
cxthread.h
1
/*
2
* This file is part of the ESO C Extension Library
3
* Copyright (C) 2001-2026 European Southern Observatory
4
*
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
9
*
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
17
*/
18
19
#ifndef CXTHREAD_H_
20
#define CXTHREAD_H_
21
22
#if HAVE_CONFIG_H
23
# include "config.h"
24
#endif
25
26
#ifdef HAVE_PTHREAD_H
27
# include <pthread.h>
28
#endif
29
30
31
/*
32
* Map local types and functions to the POSIX thread model implementation
33
*/
34
35
#if defined(CX_THREADS_ENABLED)
36
37
# if defined(HAVE_PTHREAD_H)
38
39
# define CX_STATIC_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
40
# define CX_STATIC_ONCE_INIT PTHREAD_ONCE_INIT
41
42
# define CX_MUTEX_TYPE_DEFAULT PTHREAD_MUTEX_DEFAULT
43
# define CX_MUTEX_TYPE_NORMAL PTHREAD_MUTEX_NORMAL
44
# define CX_MUTEX_TYPE_RECURSIVE PTHREAD_MUTEX_RECURSIVE
45
46
typedef
pthread_mutex_t cx_mutex;
47
typedef
pthread_once_t cx_once;
48
typedef
pthread_key_t cx_private;
49
50
# define cx_mutex_init(mutex, type) \
51
do { \
52
pthread_mutexattr_t attr; \
53
\
54
pthread_mutexattr_init(&attr); \
55
pthread_mutexattr_settype(&attr, (type)); \
56
\
57
pthread_mutex_init(mutex, &attr); \
58
\
59
pthread_mutexattr_destroy(&attr); \
60
} while (0)
61
62
# define cx_mutex_lock(mutex) pthread_mutex_lock((mutex))
63
# define cx_mutex_trylock(mutex) pthread_mutex_trylock((mutex))
64
# define cx_mutex_unlock(mutex) pthread_mutex_unlock((mutex))
65
66
# define cx_thread_once(name, func, args) pthread_once(&(name), (func))
67
68
# define cx_private_init(name, func) pthread_key_create(&(name), (func))
69
# define cx_private_set(name, data) pthread_setspecific((name), (data))
70
# define cx_private_get(name) pthread_getspecific((name))
71
72
# else
/* !HAVE_PTHREAD_H */
73
# error "Thread support is requested, but POSIX thread model is not present!"
74
# endif
/* !HAVE_PTHREAD_H */
75
76
#else
/* !CX_THREADS_ENABLED */
77
78
typedef
struct
cx_private cx_private;
79
80
# define cx_mutex_init(mutex, type)
/* empty */
81
82
# define cx_mutex_lock(mutex)
/* empty */
83
# define cx_mutex_trylock(mutex)
/* empty */
84
# define cx_mutex_unlock(mutex)
/* empty */
85
86
# define cx_thread_once(name, func, args) (func)()
87
88
# define cx_private_init(name, func)
/* empty */
89
# define cx_private_set(name, data) ((name) = (data))
90
# define cx_private_get(name) (name)
91
92
#endif
/* !CX_THREADS_ENABLED */
93
94
95
/*
96
* Convenience macros to setup locks for global variables.
97
* These macros expand to nothing, if thread support was not enabled.
98
*/
99
100
#define CX_LOCK_NAME(name) _cx__##name##_lock
101
102
#if defined(CX_THREADS_ENABLED)
103
104
# define CX_LOCK_DEFINE_STATIC(name) static CX_LOCK_DEFINE(name)
105
# define CX_LOCK_DEFINE(name) cx_mutex CX_LOCK_NAME(name)
106
# define CX_LOCK_EXTERN(name) extern cx_mutex CX_LOCK_NAME(name)
107
108
# define CX_LOCK_DEFINE_INITIALIZED_STATIC(name) \
109
static CX_LOCK_DEFINE_INITIALIZED(name)
110
# define CX_LOCK_DEFINE_INITIALIZED(name) \
111
CX_LOCK_DEFINE(name) = CX_STATIC_MUTEX_INIT
112
113
# define CX_INITLOCK(name, type) cx_mutex_init(&CX_LOCK_NAME(name), (type))
114
115
# define CX_LOCK(name) cx_mutex_lock(&CX_LOCK_NAME(name))
116
# define CX_TRYLOCK(name) cx_mutex_trylock(&CX_LOCK_NAME(name))
117
# define CX_UNLOCK(name) cx_mutex_unlock(&CX_LOCK_NAME(name))
118
119
#else
/* !CX_THREADS_ENABLED */
120
121
# define CX_LOCK_DEFINE_STATIC(name)
/* empty */
122
# define CX_LOCK_DEFINE(name)
/* empty */
123
# define CX_LOCK_EXTERN(name)
/* empty */
124
125
# define CX_LOCK_DEFINE_INITIALIZED_STATIC(name)
/* empty */
126
# define CX_LOCK_DEFINE_INITIALIZED(name)
/* empty */
127
128
# define CX_INITLOCK(name, type)
/* empty */
129
130
# define CX_LOCK(name)
/* empty */
131
# define CX_TRYLOCK(name) (TRUE)
132
# define CX_UNLOCK(name)
/* empty */
133
134
#endif
/* !CX_THREADS_ENABLED */
135
136
137
/*
138
* Convenience macros for setting up mutexes for one time initalizations
139
*/
140
141
#if defined(CX_THREADS_ENABLED)
142
143
# define CX_ONCE_DEFINE_STATIC(name) static CX_ONCE_DEFINE(name)
144
# define CX_ONCE_DEFINE(name) cx_once(name)
145
146
# define CX_ONCE_DEFINE_INITIALIZED_STATIC(name) \
147
static CX_ONCE_DEFINE_INITIALIZED(name)
148
# define CX_ONCE_DEFINE_INITIALIZED(name) cx_once(name) = CX_STATIC_ONCE_INIT
149
150
#else
/* !CX_THREADS_ENABLED */
151
152
# define CX_ONCE_DEFINE_STATIC(name)
/* empty */
153
# define CX_ONCE_DEFINE(name)
/* empty */
154
155
# define CX_ONCE_DEFINE_INITIALIZED_STATIC(name)
/* empty */
156
# define CX_ONCE_DEFINE_INITIALIZED(name)
/* empty */
157
158
#endif
/* !CX_THREADS_ENABLED */
159
160
161
/*
162
* Convenience macros for setting up thread-specific data
163
*/
164
165
#if defined(CX_THREADS_ENABLED)
166
167
# define CX_PRIVATE_DEFINE_STATIC(name) cx_private(name)
168
169
#else
/* !CX_THREADS_ENABLED */
170
171
# define CX_PRIVATE_DEFINE_STATIC(name) static cx_private *(name)
172
173
#endif
/* !CX_THREADS_ENABLED */
174
175
#endif
/* CXTHREAD_H_ */
Generated by
1.9.8