All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
threads.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 #ifndef _FR_THREADS_H
17 #define _FR_THREADS_H
18 /**
19  * $Id: 56d744debee4e4a2580672e3fee83040aa722ae5 $
20  *
21  * @file include/threads.h
22  * @brief Macros to abstract Thread Local Storage
23  *
24  * @copyright 2013 The FreeRADIUS server project
25  */
26 typedef void (*pthread_destructor_t)(void*);
27 
28 #if !defined(HAVE_PTHREAD_H) && defined(WITH_THREADS)
29 # error WITH_THREADS defined, but pthreads not available
30 #endif
31 
32 /*
33  * First figure whether we have compiler support.
34  */
35 #ifdef TLS_STORAGE_CLASS
36 # define _fr_thread_local TLS_STORAGE_CLASS
37 #endif
38 
39 /*
40  * Now we define three macros for initialisation, updating, and retrieving
41  */
42 #ifndef WITH_THREADS
43 # define fr_thread_local_setup(_t, _n) static _t _n;\
44 static inline int __fr_thread_local_destructor_##_n(pthread_destructor_t *ctx)\
45 {\
46  pthread_destructor_t func = *ctx;\
47  func(_n);\
48  return 0;\
49 }\
50 static inline _t __fr_thread_local_init_##_n(pthread_destructor_t func)\
51 {\
52  static pthread_destructor_t *ctx;\
53  if (!ctx) {\
54  ctx = talloc(talloc_autofree_context(), pthread_destructor_t);\
55  talloc_set_destructor(ctx, __fr_thread_local_destructor_##_n);\
56  *ctx = func;\
57  }\
58  return _n;\
59 }
60 # define fr_thread_local_init(_n, _f) __fr_thread_local_init_##_n(_f)
61 # define fr_thread_local_set(_n, _v) ((int)!((_n = _v) || 1))
62 # define fr_thread_local_get(_n) _n
63 # undef _fr_thread_local
64 # define _fr_thread_local
65 #elif defined(_fr_thread_local)
66 # include <pthread.h>
67 # define fr_thread_local_setup(_t, _n) static _fr_thread_local _t _n;\
68 static pthread_key_t __fr_thread_local_key_##_n;\
69 static pthread_once_t __fr_thread_local_once_##_n = PTHREAD_ONCE_INIT;\
70 static pthread_destructor_t __fr_thread_local_destructor_##_n = NULL;\
71 static inline void __fr_thread_local_key_init_##_n(void)\
72 {\
73  (void) pthread_key_create(&__fr_thread_local_key_##_n, __fr_thread_local_destructor_##_n);\
74 }\
75 static inline _t __fr_thread_local_init_##_n(pthread_destructor_t func)\
76 {\
77  __fr_thread_local_destructor_##_n = func;\
78  (void) pthread_once(&__fr_thread_local_once_##_n, __fr_thread_local_key_init_##_n);\
79  return _n;\
80 }
81 # define fr_thread_local_init(_n, _f) __fr_thread_local_init_##_n(_f)
82 # define fr_thread_local_set(_n, _v) ((int)!((_n = _v) || 1))
83 # define fr_thread_local_get(_n) _n
84 #endif
85 #endif /* _FR_THREADS_H */
void(* pthread_destructor_t)(void *)
Definition: threads.h:26