49#ifndef ASTERISK_THREADSTORAGE_H
50#define ASTERISK_THREADSTORAGE_H
65#if defined(DEBUG_THREADLOCALS)
66void __ast_threadstorage_object_add(
void *key,
size_t len,
const char *
file,
const char *function,
unsigned int line);
67void __ast_threadstorage_object_remove(
void *key);
68void __ast_threadstorage_object_replace(
void *key_old,
void *key_new,
size_t len);
69#define THREADSTORAGE_RAW_CLEANUP(v) {}
71#define THREADSTORAGE_RAW_CLEANUP NULL
86#define AST_THREADSTORAGE(name) \
87 AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr, static)
88#define AST_THREADSTORAGE_PUBLIC(name) \
89 AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, ast_free_ptr,)
90#define AST_THREADSTORAGE_EXTERNAL(name) \
91 extern struct ast_threadstorage name
92#define AST_THREADSTORAGE_RAW(name) \
93 AST_THREADSTORAGE_CUSTOM_SCOPE(name, NULL, THREADSTORAGE_RAW_CLEANUP,)
111#define AST_THREADSTORAGE_CUSTOM(a,b,c) AST_THREADSTORAGE_CUSTOM_SCOPE(a,b,c,static)
113#if defined(PTHREAD_ONCE_INIT_NEEDS_BRACES)
114# define AST_PTHREAD_ONCE_INIT { PTHREAD_ONCE_INIT }
116# define AST_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
119#if !defined(DEBUG_THREADLOCALS)
120#define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \
121static void __init_##name(void); \
122scope struct ast_threadstorage name = { \
123 .once = AST_PTHREAD_ONCE_INIT, \
124 .key_init = __init_##name, \
125 .custom_init = c_init, \
127static void __init_##name(void) \
129 pthread_key_create(&(name).key, c_cleanup); \
132#define AST_THREADSTORAGE_CUSTOM_SCOPE(name, c_init, c_cleanup, scope) \
133static void __init_##name(void); \
134scope struct ast_threadstorage name = { \
135 .once = AST_PTHREAD_ONCE_INIT, \
136 .key_init = __init_##name, \
137 .custom_init = c_init, \
139static void __cleanup_##name(void *data) \
141 __ast_threadstorage_object_remove(data); \
144static void __init_##name(void) \
146 pthread_key_create(&(name).key, __cleanup_##name); \
179#if !defined(DEBUG_THREADLOCALS)
186 if (!(
buf = pthread_getspecific(ts->
key))) {
194 pthread_setspecific(ts->
key,
buf);
202void *__ast_threadstorage_get(
struct ast_threadstorage *ts,
size_t init_size,
const char *
file,
const char *function,
unsigned int line),
207 if (!(
buf = pthread_getspecific(ts->
key))) {
215 pthread_setspecific(ts->
key,
buf);
216 __ast_threadstorage_object_add(
buf, init_size,
file, function, line);
223#define
ast_threadstorage_get(ts, init_size) __ast_threadstorage_get(ts, init_size, __FILE__, __PRETTY_FUNCTION__, __LINE__)
241 return pthread_getspecific(ts->
key);
261 return pthread_setspecific(ts->
key, ptr);
#define ast_calloc(num, len)
A wrapper for calloc()
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Inlinable API function macro.
#define AST_INLINE_API(hdr, body)
data for a thread locally stored variable
int(* custom_init)(void *)
int ast_threadstorage_set_ptr(struct ast_threadstorage *ts, void *ptr)
Set a raw pointer from threadstorage.
void * ast_threadstorage_get_ptr(struct ast_threadstorage *ts)
Retrieve a raw pointer from threadstorage.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.