47 #ifndef ASTERISK_THREADSTORAGE_H
48 #define ASTERISK_THREADSTORAGE_H
63 #if defined(DEBUG_THREADLOCALS)
64 void __ast_threadstorage_object_add(
void *key,
size_t len,
const char *file,
const char *
function,
unsigned int line);
65 void __ast_threadstorage_object_remove(
void *key);
66 void __ast_threadstorage_object_replace(
void *key_old,
void *key_new,
size_t len);
81 #define AST_THREADSTORAGE(name) \
82 AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr, static)
83 #define AST_THREADSTORAGE_PUBLIC(name) \
84 AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr,)
85 #define AST_THREADSTORAGE_EXTERNAL(name) \
86 extern struct ast_threadstorage name
104 #define AST_THREADSTORAGE_CUSTOM(a,b,c) AST_THREADSTORAGE_CUSTOM_SCOPE(a,b,c,static)
106 #if defined(PTHREAD_ONCE_INIT_NEEDS_BRACES)
107 # define AST_PTHREAD_ONCE_INIT { PTHREAD_ONCE_INIT }
109 # define AST_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
112 #if !defined(DEBUG_THREADLOCALS)
113 #define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \
114 static void __init_##name(void); \
115 scope struct ast_threadstorage name = { \
116 .once = AST_PTHREAD_ONCE_INIT, \
117 .key_init = __init_##name, \
118 .custom_init = c_init, \
120 static void __init_##name(void) \
122 pthread_key_create(&(name).key, c_cleanup); \
125 #define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \
126 static void __init_##name(void); \
127 scope struct ast_threadstorage name = { \
128 .once = AST_PTHREAD_ONCE_INIT, \
129 .key_init = __init_##name, \
130 .custom_init = c_init, \
132 static void __cleanup_##name(void *data) \
134 __ast_threadstorage_object_remove(data); \
137 static void __init_##name(void) \
139 pthread_key_create(&(name).key, __cleanup_##name); \
172 #if !defined(DEBUG_THREADLOCALS)
179 if (!(buf = pthread_getspecific(ts->
key))) {
186 pthread_setspecific(ts->
key, buf);
194 void *__ast_threadstorage_get(
struct ast_threadstorage *ts,
size_t init_size,
const char *file,
const char *
function,
unsigned int line),
199 if (!(buf = pthread_getspecific(ts->
key))) {
206 pthread_setspecific(ts->
key, buf);
207 __ast_threadstorage_object_add(buf, init_size, file,
function, line);
214 #define
ast_threadstorage_get(ts, init_size) __ast_threadstorage_get(ts, init_size, __FILE__, __PRETTY_FUNCTION__, __LINE__)
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
int(* custom_init)(void *)
data for a thread locally stored variable
Inlinable API function macro.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_INLINE_API(hdr, body)