NCBI C++ ToolKit
thread.h
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2  *
3  * Copyright (C) 2005 Liam Widdowson
4  * Copyright (C) 2010-2012 Frediano Ziglio
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
22 #ifndef TDSTHREAD_H
23 #define TDSTHREAD_H 1
24 
25 #undef TDS_HAVE_MUTEX
26 
27 #if defined(_THREAD_SAFE) && defined(TDS_HAVE_PTHREAD_MUTEX)
28 
29 #include <pthread.h>
30 
31 #include <freetds/pushvis.h>
32 
33 typedef pthread_mutex_t tds_raw_mutex;
34 #define TDS_RAW_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
35 
36 static inline void tds_raw_mutex_lock(tds_raw_mutex *mtx)
37 {
38  pthread_mutex_lock(mtx);
39 }
40 
41 static inline int tds_raw_mutex_trylock(tds_raw_mutex *mtx)
42 {
43  return pthread_mutex_trylock(mtx);
44 }
45 
46 static inline void tds_raw_mutex_unlock(tds_raw_mutex *mtx)
47 {
48  pthread_mutex_unlock(mtx);
49 }
50 
51 static inline int tds_raw_mutex_init(tds_raw_mutex *mtx)
52 {
53  return pthread_mutex_init(mtx, NULL);
54 }
55 
56 static inline void tds_raw_mutex_free(tds_raw_mutex *mtx)
57 {
58  pthread_mutex_destroy(mtx);
59 }
60 
61 typedef pthread_cond_t tds_condition;
62 
64 static inline int tds_raw_cond_destroy(tds_condition *cond)
65 {
66  return pthread_cond_destroy(cond);
67 }
68 static inline int tds_raw_cond_signal(tds_condition *cond)
69 {
70  return pthread_cond_signal(cond);
71 }
72 static inline int tds_raw_cond_wait(tds_condition *cond, tds_raw_mutex *mtx)
73 {
74  return pthread_cond_wait(cond, mtx);
75 }
76 int tds_raw_cond_timedwait(tds_condition *cond, tds_raw_mutex *mtx, int timeout_sec);
77 
78 #define TDS_HAVE_MUTEX 1
79 
80 typedef pthread_t tds_thread;
81 typedef pthread_t tds_thread_id;
82 typedef void *(*tds_thread_proc)(void *arg);
83 #define TDS_THREAD_PROC_DECLARE(name, arg) \
84  void *name(void *arg)
85 
86 static inline int tds_thread_create(tds_thread *ret, tds_thread_proc proc, void *arg)
87 {
88  return pthread_create(ret, NULL, proc, arg);
89 }
90 
91 static inline int tds_thread_create_detached(tds_thread_proc proc, void *arg)
92 {
93  tds_thread th;
94  int ret = pthread_create(&th, NULL, proc, arg);
95  if (!ret)
96  pthread_detach(th);
97  return ret;
98 }
99 
100 static inline int tds_thread_join(tds_thread th, void **ret)
101 {
102  return pthread_join(th, ret);
103 }
104 
105 static inline tds_thread_id tds_thread_get_current_id(void)
106 {
107  return pthread_self();
108 }
109 
110 static inline int tds_thread_is_current(tds_thread_id th)
111 {
112  return pthread_equal(th, pthread_self());
113 }
114 
115 #include <freetds/popvis.h>
116 
117 #elif defined(_WIN32)
118 
119 struct ptw32_mcs_node_t_;
120 
121 typedef struct {
122  struct ptw32_mcs_node_t_ *lock;
123  LONG done;
124  CRITICAL_SECTION crit;
125 } tds_raw_mutex;
126 
127 #define TDS_RAW_MUTEX_INITIALIZER { NULL, 0 }
128 
129 static inline int
131 {
132  mtx->lock = NULL;
133  mtx->done = 0;
134  return 0;
135 }
136 
137 void tds_win_mutex_lock(tds_raw_mutex *mutex);
138 
139 static inline void tds_raw_mutex_lock(tds_raw_mutex *mtx)
140 {
141  if ((mtx)->done)
142  EnterCriticalSection(&(mtx)->crit);
143  else
144  tds_win_mutex_lock(mtx);
145 }
146 
148 
149 static inline void tds_raw_mutex_unlock(tds_raw_mutex *mtx)
150 {
151  LeaveCriticalSection(&(mtx)->crit);
152 }
153 
154 static inline void tds_raw_mutex_free(tds_raw_mutex *mtx)
155 {
156  if ((mtx)->done) {
157  DeleteCriticalSection(&(mtx)->crit);
158  (mtx)->done = 0;
159  }
160 }
161 
162 #define TDS_HAVE_MUTEX 1
163 
164 /* easy way, only single signal supported */
165 typedef void *TDS_CONDITION_VARIABLE;
166 typedef union {
167  HANDLE ev;
168  TDS_CONDITION_VARIABLE cv;
169 } tds_condition;
170 
171 extern int (*tds_raw_cond_init)(tds_condition *cond);
172 extern int (*tds_raw_cond_destroy)(tds_condition *cond);
173 extern int (*tds_raw_cond_signal)(tds_condition *cond);
174 extern int (*tds_raw_cond_timedwait)(tds_condition *cond, tds_raw_mutex *mtx, int timeout_sec);
175 static inline int tds_raw_cond_wait(tds_condition *cond, tds_raw_mutex *mtx)
176 {
177  return tds_raw_cond_timedwait(cond, mtx, -1);
178 }
179 
180 typedef HANDLE tds_thread;
181 typedef DWORD tds_thread_id;
182 typedef LPTHREAD_START_ROUTINE tds_thread_proc;
183 #define TDS_THREAD_PROC_DECLARE(name, arg) \
184  DWORD name(void *arg)
185 
186 static inline int tds_thread_create(tds_thread *ret, tds_thread_proc proc, void *arg)
187 {
188  *ret = CreateThread(NULL, 0, (DWORD (WINAPI *)(void*)) proc, arg, 0, NULL);
189  return *ret != NULL ? 0 : 11 /* EAGAIN */;
190 }
191 
192 static inline int tds_thread_create_detached(tds_thread_proc proc, void *arg)
193 {
194  HANDLE h = CreateThread(NULL, 0, (DWORD (WINAPI *)(void*)) proc, arg, 0, NULL);
195  if (h)
196  return 0;
197  CloseHandle(h);
198  return 11 /* EAGAIN */;
199 }
200 
201 static inline int tds_thread_join(tds_thread th, void **ret)
202 {
203  if (WaitForSingleObject(th, INFINITE) == WAIT_OBJECT_0) {
204  DWORD r;
205  if (ret && GetExitCodeThread(th, &r))
206  *ret = (void*) (((char*)0) + r);
207 
208  CloseHandle(th);
209  return 0;
210  }
211  CloseHandle(th);
212  return 22 /* EINVAL */;
213 }
214 
215 static inline tds_thread_id tds_thread_get_current_id(void)
216 {
217  return GetCurrentThreadId();
218 }
219 
220 static inline int tds_thread_is_current(tds_thread_id th)
221 {
222  return th == GetCurrentThreadId();
223 }
224 
225 #else
226 
227 /* define noops as "successful" */
228 typedef struct {
229 } tds_raw_mutex;
230 
231 #define TDS_RAW_MUTEX_INITIALIZER {}
232 
234 {
235 }
236 
238 {
239  return 0;
240 }
241 
243 {
244 }
245 
247 {
248  return 0;
249 }
250 
252 {
253 }
254 
255 typedef struct {
256 } tds_condition;
257 
258 static inline int tds_raw_cond_init(tds_condition *cond)
259 {
260  return 0;
261 }
262 static inline int tds_raw_cond_destroy(tds_condition *cond)
263 {
264  return 0;
265 }
266 #define tds_raw_cond_signal(cond) \
267  FreeTDS_Condition_not_compiled
268 
269 #define tds_raw_cond_wait(cond, mtx) \
270  FreeTDS_Condition_not_compiled
271 
272 #define tds_raw_cond_timedwait(cond, mtx, timeout_sec) \
273  FreeTDS_Condition_not_compiled
274 
275 typedef struct {
276 } tds_thread;
277 typedef int tds_thread_id;
278 
279 typedef void *(*tds_thread_proc)(void *arg);
280 #define TDS_THREAD_PROC_DECLARE(name, arg) \
281  void *name(void *arg)
282 
283 #define tds_thread_create(ret, proc, arg) \
284  FreeTDS_Thread_not_compiled
285 
286 #define tds_thread_create_detached(proc, arg) \
287  FreeTDS_Thread_not_compiled
288 
289 #define tds_thread_join(th, ret) \
290  FreeTDS_Thread_not_compiled
291 
293 {
294  return 0;
295 }
296 
298 {
299  return 1;
300 }
301 
302 
303 #endif
304 
305 #ifdef TDS_HAVE_MUTEX
306 # define tds_cond_init tds_raw_cond_init
307 # define tds_cond_destroy tds_raw_cond_destroy
308 # define tds_cond_signal tds_raw_cond_signal
309 # if !ENABLE_EXTRA_CHECKS
310 # define TDS_MUTEX_INITIALIZER TDS_RAW_MUTEX_INITIALIZER
311 # define tds_mutex tds_raw_mutex
312 # define tds_mutex_lock tds_raw_mutex_lock
313 # define tds_mutex_trylock tds_raw_mutex_trylock
314 # define tds_mutex_unlock tds_raw_mutex_unlock
315 # define tds_mutex_check_owned(mtx) do {} while(0)
316 # define tds_mutex_init tds_raw_mutex_init
317 # define tds_mutex_free tds_raw_mutex_free
318 # define tds_cond_wait tds_raw_cond_wait
319 # define tds_cond_timedwait tds_raw_cond_timedwait
320 # else
321 # include <assert.h>
322 
323 typedef struct tds_mutex
324 {
326  volatile int locked;
327  volatile tds_thread_id locked_by;
328 } tds_mutex;
329 
330 # define TDS_MUTEX_INITIALIZER { TDS_RAW_MUTEX_INITIALIZER, 0 }
331 
332 static inline void tds_mutex_lock(tds_mutex *mtx)
333 {
334  assert(mtx);
335  tds_raw_mutex_lock(&mtx->mtx);
336  assert(!mtx->locked);
337  mtx->locked = 1;
338  mtx->locked_by = tds_thread_get_current_id();
339 }
340 
341 static inline int tds_mutex_trylock(tds_mutex *mtx)
342 {
343  int ret;
344  assert(mtx);
345  ret = tds_raw_mutex_trylock(&mtx->mtx);
346  if (!ret) {
347 #ifdef _WIN32
348  /* disallow recursive locking! */
349  if (mtx->locked
350  && mtx->locked_by == tds_thread_get_current_id()) {
351  tds_raw_mutex_unlock(&mtx->mtx);
352  return -1;
353  }
354 #endif
355  assert(!mtx->locked);
356  mtx->locked = 1;
357  mtx->locked_by = tds_thread_get_current_id();
358  }
359  return ret;
360 }
361 
362 static inline void tds_mutex_unlock(tds_mutex *mtx)
363 {
364  assert(mtx && mtx->locked);
365  mtx->locked = 0;
366  tds_raw_mutex_unlock(&mtx->mtx);
367 }
368 
369 static inline void tds_mutex_check_owned(tds_mutex *mtx)
370 {
371  int ret;
372  assert(mtx);
373  ret = tds_raw_mutex_trylock(&mtx->mtx);
374  assert(ret);
375  assert(mtx->locked);
376  assert(tds_thread_is_current(mtx->locked_by));
377 }
378 
379 static inline int tds_mutex_init(tds_mutex *mtx)
380 {
381  mtx->locked = 0;
382  return tds_raw_mutex_init(&mtx->mtx);
383 }
384 
385 static inline void tds_mutex_free(tds_mutex *mtx)
386 {
387  assert(mtx && !mtx->locked);
388  tds_raw_mutex_free(&mtx->mtx);
389 }
390 
391 static inline int tds_cond_wait(tds_condition *cond, tds_mutex *mtx)
392 {
393  int ret;
394  assert(mtx && mtx->locked);
395  mtx->locked = 0;
396  ret = tds_raw_cond_wait(cond, &mtx->mtx);
397  mtx->locked = 1;
398  mtx->locked_by = tds_thread_get_current_id();
399  return ret;
400 }
401 
402 static inline int tds_cond_timedwait(tds_condition *cond, tds_mutex *mtx, int timeout_sec)
403 {
404  int ret;
405  assert(mtx && mtx->locked);
406  mtx->locked = 0;
407  ret = tds_raw_cond_timedwait(cond, &mtx->mtx, timeout_sec);
408  mtx->locked = 1;
409  mtx->locked_by = tds_thread_get_current_id();
410  return ret;
411 }
412 
413 # endif
414 #else
415 static inline int tds_mutex_noop(void)
416 {
417  return 0;
418 }
419 # define tds_mutex_free(x) do {} while (0)
420 # define tds_mutex_init(x) tds_mutex_noop()
421 # define tds_mutex_lock(x) tds_mutex_noop()
422 # define tds_mutex_trylock(x) tds_mutex_noop()
423 # define tds_mutex_unlock(x) do {} while (0)
424 #endif
425 
426 #endif
#define tds_raw_cond_timedwait(cond, mtx, timeout_sec)
Definition: thread.h:272
static tds_thread_id tds_thread_get_current_id(void)
Definition: thread.h:292
#define tds_mutex_trylock(x)
Definition: thread.h:422
#define tds_thread_create(ret, proc, arg)
Definition: thread.h:283
static void tds_raw_mutex_free(tds_raw_mutex *mtx)
Definition: thread.h:251
#define tds_mutex_free(x)
Definition: thread.h:419
int tds_thread_id
Definition: thread.h:277
void *(* tds_thread_proc)(void *arg)
Definition: thread.h:279
static int tds_raw_mutex_init(tds_raw_mutex *mtx)
Definition: thread.h:246
#define tds_mutex_lock(x)
Definition: thread.h:421
static int tds_thread_is_current(tds_thread_id th)
Definition: thread.h:297
static void tds_raw_mutex_unlock(tds_raw_mutex *mtx)
Definition: thread.h:242
static void tds_raw_mutex_lock(tds_raw_mutex *mtx)
Definition: thread.h:233
static int tds_raw_mutex_trylock(tds_raw_mutex *mtx)
Definition: thread.h:237
#define tds_raw_cond_signal(cond)
Definition: thread.h:266
static int tds_raw_cond_destroy(tds_condition *cond)
Definition: thread.h:262
static int tds_mutex_noop(void)
Definition: thread.h:415
#define tds_mutex_unlock(x)
Definition: thread.h:423
#define tds_thread_create_detached(proc, arg)
Definition: thread.h:286
#define tds_raw_cond_wait(cond, mtx)
Definition: thread.h:269
#define tds_mutex_init(x)
Definition: thread.h:420
#define tds_thread_join(th, ret)
Definition: thread.h:289
static int tds_raw_cond_init(tds_condition *cond)
Definition: thread.h:258
static const char * proc
Definition: stats.c:21
static tds_mutex mtx
Definition: condition.c:43
#define tds_cond_timedwait
Definition: thread.h:344
#define tds_cond_wait
Definition: thread.h:343
#define tds_mutex_check_owned(mtx)
Definition: thread.h:340
#define tds_mutex
Definition: thread.h:336
#define NULL
Definition: ncbistd.hpp:225
#define HANDLE
An abstraction for a file handle.
Definition: mdb.c:383
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
<!DOCTYPE HTML >< html > n< header > n< title > PubSeq Gateway Help Page</title > n< style > n th
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
unsigned int DWORD
Definition: sqltypes.h:98
#define assert(x)
Definition: srv_diag.hpp:58
struct ptw32_mcs_node_t_ ** lock
done
Definition: token1.c:1
Modified on Fri Sep 20 14:58:00 2024 by modify_doxy.py rev. 669887