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 <tds_sysdep_public.h>
30 #include <freetds/sysdep_types.h>
31 #include <pthread.h>
32 #include <errno.h>
33 
34 #include <freetds/pushvis.h>
35 
36 typedef pthread_mutex_t tds_raw_mutex;
37 #define TDS_RAW_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
38 
39 static inline void tds_raw_mutex_lock(tds_raw_mutex *mtx)
40 {
41  pthread_mutex_lock(mtx);
42 }
43 
44 static inline int tds_raw_mutex_trylock(tds_raw_mutex *mtx)
45 {
46  return pthread_mutex_trylock(mtx);
47 }
48 
49 static inline void tds_raw_mutex_unlock(tds_raw_mutex *mtx)
50 {
51  pthread_mutex_unlock(mtx);
52 }
53 
54 static inline int tds_raw_mutex_init(tds_raw_mutex *mtx)
55 {
56  return pthread_mutex_init(mtx, NULL);
57 }
58 
59 static inline void tds_raw_mutex_free(tds_raw_mutex *mtx)
60 {
61  pthread_mutex_destroy(mtx);
62 }
63 
64 typedef pthread_cond_t tds_condition;
65 
67 static inline int tds_raw_cond_destroy(tds_condition *cond)
68 {
69  return pthread_cond_destroy(cond);
70 }
71 static inline int tds_raw_cond_signal(tds_condition *cond)
72 {
73  return pthread_cond_signal(cond);
74 }
75 static inline int tds_raw_cond_wait(tds_condition *cond, tds_raw_mutex *mtx)
76 {
77  return pthread_cond_wait(cond, mtx);
78 }
79 int tds_raw_cond_timedwait(tds_condition *cond, tds_raw_mutex *mtx, int timeout_sec);
80 
81 #define TDS_HAVE_MUTEX 1
82 
83 typedef pthread_t tds_thread;
84 typedef pthread_t tds_thread_id;
85 typedef void *(*tds_thread_proc)(void *arg);
86 #define TDS_THREAD_PROC_DECLARE(name, arg) \
87  void *name(void *arg)
88 #define TDS_THREAD_RESULT(n) ((void*)(TDS_INTPTR)(n))
89 
90 static inline int tds_thread_create(tds_thread *ret, tds_thread_proc proc, void *arg)
91 {
92  return pthread_create(ret, NULL, proc, arg);
93 }
94 
95 static inline int tds_thread_create_detached(tds_thread_proc proc, void *arg)
96 {
97  tds_thread th;
98  int ret = pthread_create(&th, NULL, proc, arg);
99  if (!ret)
100  pthread_detach(th);
101  return ret;
102 }
103 
104 static inline int tds_thread_join(tds_thread th, void **ret)
105 {
106  return pthread_join(th, ret);
107 }
108 
109 static inline tds_thread_id tds_thread_get_current_id(void)
110 {
111  return pthread_self();
112 }
113 
114 static inline int tds_thread_is_current(tds_thread_id th)
115 {
116  return pthread_equal(th, pthread_self());
117 }
118 
119 #include <freetds/popvis.h>
120 
121 #elif defined(_WIN32)
122 
123 #include <freetds/windows.h>
124 #include <errno.h>
125 
126 /* old version of Windows do not define this constant */
127 #ifndef ETIMEDOUT
128 #define ETIMEDOUT 138
129 #endif
130 
131 struct ptw32_mcs_node_t_;
132 
133 typedef struct {
134  struct ptw32_mcs_node_t_ *lock;
135  LONG done;
136  DWORD thread_id;
137  CRITICAL_SECTION crit;
138 } tds_raw_mutex;
139 
140 #define TDS_RAW_MUTEX_INITIALIZER { NULL, 0, 0 }
141 
142 static inline int
144 {
145  mtx->lock = NULL;
146  mtx->done = 0;
147  mtx->thread_id = 0;
148  return 0;
149 }
150 
151 void tds_win_mutex_lock(tds_raw_mutex *mutex);
152 
153 static inline void tds_raw_mutex_lock(tds_raw_mutex *mtx)
154 {
155  if (mtx->done) {
156  EnterCriticalSection(&mtx->crit);
157  mtx->thread_id = GetCurrentThreadId();
158  } else {
159  tds_win_mutex_lock(mtx);
160  }
161 }
162 
164 
165 static inline void tds_raw_mutex_unlock(tds_raw_mutex *mtx)
166 {
167  mtx->thread_id = 0;
168  LeaveCriticalSection(&mtx->crit);
169 }
170 
171 static inline void tds_raw_mutex_free(tds_raw_mutex *mtx)
172 {
173  if (mtx->done) {
174  DeleteCriticalSection(&mtx->crit);
175  mtx->done = 0;
176  }
177 }
178 
179 #define TDS_HAVE_MUTEX 1
180 
181 /* easy way, only single signal supported */
182 typedef void *TDS_CONDITION_VARIABLE;
183 typedef union {
184  HANDLE ev;
185  TDS_CONDITION_VARIABLE cv;
186 } tds_condition;
187 
188 extern int (*tds_raw_cond_init)(tds_condition *cond);
189 extern int (*tds_raw_cond_destroy)(tds_condition *cond);
190 extern int (*tds_raw_cond_signal)(tds_condition *cond);
191 extern int (*tds_raw_cond_timedwait)(tds_condition *cond, tds_raw_mutex *mtx, int timeout_sec);
192 static inline int tds_raw_cond_wait(tds_condition *cond, tds_raw_mutex *mtx)
193 {
194  return tds_raw_cond_timedwait(cond, mtx, -1);
195 }
196 
197 typedef HANDLE tds_thread;
198 typedef DWORD tds_thread_id;
199 typedef DWORD (WINAPI *tds_thread_proc)(void *arg);
200 #define TDS_THREAD_PROC_DECLARE(name, arg) \
201  DWORD WINAPI name(void *arg)
202 #define TDS_THREAD_RESULT(n) ((DWORD)(int)(n))
203 
204 static inline int tds_thread_create(tds_thread *ret, tds_thread_proc proc, void *arg)
205 {
206  *ret = CreateThread(NULL, 0, proc, arg, 0, NULL);
207  return *ret != NULL ? 0 : 11 /* EAGAIN */;
208 }
209 
210 static inline int tds_thread_create_detached(tds_thread_proc proc, void *arg)
211 {
212  HANDLE h = CreateThread(NULL, 0, proc, arg, 0, NULL);
213  if (h)
214  return 0;
215  CloseHandle(h);
216  return 11 /* EAGAIN */;
217 }
218 
219 static inline int tds_thread_join(tds_thread th, void **ret)
220 {
221  if (WaitForSingleObject(th, INFINITE) == WAIT_OBJECT_0) {
222  if (ret) {
223  DWORD r;
224  if (!GetExitCodeThread(th, &r))
225  r = 0xffffffffu;
226  *ret = (void*) (((char*)0) + r);
227  }
228 
229  CloseHandle(th);
230  return 0;
231  }
232  CloseHandle(th);
233  return 22 /* EINVAL */;
234 }
235 
236 static inline tds_thread_id tds_thread_get_current_id(void)
237 {
238  return GetCurrentThreadId();
239 }
240 
241 static inline int tds_thread_is_current(tds_thread_id th)
242 {
243  return th == GetCurrentThreadId();
244 }
245 
246 #else
247 
248 #include <tds_sysdep_public.h>
249 
250 /* define noops as "successful" */
251 typedef struct {
252  char dummy[0]; /* compiler compatibility */
253 } tds_raw_mutex;
254 
255 #define TDS_RAW_MUTEX_INITIALIZER {}
256 
258 {
259 }
260 
262 {
263  return 0;
264 }
265 
267 {
268 }
269 
271 {
272  return 0;
273 }
274 
276 {
277 }
278 
279 typedef struct {
280  char dummy[0]; /* compiler compatibility */
281 } tds_condition;
282 
283 static inline int tds_raw_cond_init(tds_condition *cond)
284 {
285  return 0;
286 }
287 static inline int tds_raw_cond_destroy(tds_condition *cond)
288 {
289  return 0;
290 }
291 #define tds_raw_cond_signal(cond) \
292  FreeTDS_Condition_not_compiled
293 
294 #define tds_raw_cond_wait(cond, mtx) \
295  FreeTDS_Condition_not_compiled
296 
297 #define tds_raw_cond_timedwait(cond, mtx, timeout_sec) \
298  FreeTDS_Condition_not_compiled
299 
300 typedef struct {
301  char dummy[0]; /* compiler compatibility */
302 } tds_thread;
303 typedef int tds_thread_id;
304 
305 typedef void *(*tds_thread_proc)(void *arg);
306 #define TDS_THREAD_PROC_DECLARE(name, arg) \
307  void *name(void *arg)
308 #define TDS_THREAD_RESULT(n) ((void*)(TDS_INTPTR)(n))
309 
310 #define tds_thread_create(ret, proc, arg) \
311  FreeTDS_Thread_not_compiled
312 
313 #define tds_thread_create_detached(proc, arg) \
314  FreeTDS_Thread_not_compiled
315 
316 #define tds_thread_join(th, ret) \
317  FreeTDS_Thread_not_compiled
318 
320 {
321  return 0;
322 }
323 
325 {
326  return 1;
327 }
328 
329 #endif
330 
331 # define tds_cond_init tds_raw_cond_init
332 # define tds_cond_destroy tds_raw_cond_destroy
333 # define tds_cond_signal tds_raw_cond_signal
334 # if !ENABLE_EXTRA_CHECKS || !defined(TDS_HAVE_MUTEX)
335 # define TDS_MUTEX_INITIALIZER TDS_RAW_MUTEX_INITIALIZER
336 # define tds_mutex tds_raw_mutex
337 # define tds_mutex_lock tds_raw_mutex_lock
338 # define tds_mutex_trylock tds_raw_mutex_trylock
339 # define tds_mutex_unlock tds_raw_mutex_unlock
340 # define tds_mutex_check_owned(mtx) do {} while(0)
341 # define tds_mutex_init tds_raw_mutex_init
342 # define tds_mutex_free tds_raw_mutex_free
343 # define tds_cond_wait tds_raw_cond_wait
344 # define tds_cond_timedwait tds_raw_cond_timedwait
345 # else
346 # include <assert.h>
347 
348 typedef struct tds_mutex
349 {
351  volatile int locked;
352  volatile tds_thread_id locked_by;
353 } tds_mutex;
354 
355 # define TDS_MUTEX_INITIALIZER { TDS_RAW_MUTEX_INITIALIZER, 0 }
356 
357 static inline void tds_mutex_lock(tds_mutex *mtx)
358 {
359  assert(mtx);
360  tds_raw_mutex_lock(&mtx->mtx);
361  assert(!mtx->locked);
362  mtx->locked = 1;
363  mtx->locked_by = tds_thread_get_current_id();
364 }
365 
366 static inline int tds_mutex_trylock(tds_mutex *mtx)
367 {
368  int ret;
369  assert(mtx);
370  ret = tds_raw_mutex_trylock(&mtx->mtx);
371  if (!ret) {
372  assert(!mtx->locked);
373  mtx->locked = 1;
374  mtx->locked_by = tds_thread_get_current_id();
375  }
376  return ret;
377 }
378 
379 static inline void tds_mutex_unlock(tds_mutex *mtx)
380 {
381  assert(mtx && mtx->locked);
382  mtx->locked = 0;
383  tds_raw_mutex_unlock(&mtx->mtx);
384 }
385 
386 static inline void tds_mutex_check_owned(tds_mutex *mtx)
387 {
388  int ret;
389  assert(mtx);
390  ret = tds_raw_mutex_trylock(&mtx->mtx);
391  assert(ret);
392  assert(mtx->locked);
393  assert(tds_thread_is_current(mtx->locked_by));
394 }
395 
396 static inline int tds_mutex_init(tds_mutex *mtx)
397 {
398  mtx->locked = 0;
399  return tds_raw_mutex_init(&mtx->mtx);
400 }
401 
402 static inline void tds_mutex_free(tds_mutex *mtx)
403 {
404  assert(mtx && !mtx->locked);
405  tds_raw_mutex_free(&mtx->mtx);
406 }
407 
408 static inline int tds_cond_wait(tds_condition *cond, tds_mutex *mtx)
409 {
410  int ret;
411  assert(mtx && mtx->locked);
412  mtx->locked = 0;
413  ret = tds_raw_cond_wait(cond, &mtx->mtx);
414  mtx->locked = 1;
415  mtx->locked_by = tds_thread_get_current_id();
416  return ret;
417 }
418 
419 static inline int tds_cond_timedwait(tds_condition *cond, tds_mutex *mtx, int timeout_sec)
420 {
421  int ret;
422  assert(mtx && mtx->locked);
423  mtx->locked = 0;
424  ret = tds_raw_cond_timedwait(cond, &mtx->mtx, timeout_sec);
425  mtx->locked = 1;
426  mtx->locked_by = tds_thread_get_current_id();
427  return ret;
428 }
429 
430 # endif
431 
432 #endif
unsigned dummy
Definition: block_cipher.h:0
int tds_thread_id
Definition: thread.h:277
void *(* tds_thread_proc)(void *arg)
Definition: thread.h:279
static const char * proc
Definition: stats.c:21
static tds_mutex mtx
Definition: condition.c:43
#define tds_mutex_trylock
Definition: thread.h:338
#define tds_mutex_lock
Definition: thread.h:337
#define tds_cond_timedwait
Definition: thread.h:344
#define tds_raw_cond_timedwait(cond, mtx, timeout_sec)
Definition: thread.h:297
static tds_thread_id tds_thread_get_current_id(void)
Definition: thread.h:319
#define tds_thread_create(ret, proc, arg)
Definition: thread.h:310
static void tds_raw_mutex_free(tds_raw_mutex *mtx)
Definition: thread.h:275
#define tds_mutex_init
Definition: thread.h:341
static int tds_raw_mutex_init(tds_raw_mutex *mtx)
Definition: thread.h:270
#define tds_mutex_unlock
Definition: thread.h:339
static int tds_thread_is_current(tds_thread_id th)
Definition: thread.h:324
#define tds_cond_wait
Definition: thread.h:343
static void tds_raw_mutex_unlock(tds_raw_mutex *mtx)
Definition: thread.h:266
#define tds_mutex_free
Definition: thread.h:342
#define tds_mutex_check_owned(mtx)
Definition: thread.h:340
static void tds_raw_mutex_lock(tds_raw_mutex *mtx)
Definition: thread.h:257
static int tds_raw_mutex_trylock(tds_raw_mutex *mtx)
Definition: thread.h:261
#define tds_raw_cond_signal(cond)
Definition: thread.h:291
static int tds_raw_cond_destroy(tds_condition *cond)
Definition: thread.h:287
#define tds_thread_create_detached(proc, arg)
Definition: thread.h:313
#define tds_raw_cond_wait(cond, mtx)
Definition: thread.h:294
#define tds_thread_join(th, ret)
Definition: thread.h:316
#define tds_mutex
Definition: thread.h:336
static int tds_raw_cond_init(tds_condition *cond)
Definition: thread.h:283
#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 Mon May 20 04:59:46 2024 by modify_doxy.py rev. 669887