mirror of
https://github.com/asterisk/asterisk.git
synced 2026-06-09 03:45:27 +00:00
Merged revisions 49553 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r49553 | kpfleming | 2007-01-04 16:51:01 -0600 (Thu, 04 Jan 2007) | 2 lines add support for tracking thread-local-storage objects that exist via 'threadstorage' CLI commands ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@49578 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -81,6 +81,7 @@ void ast_builtins_init(void); /*!< Provided by cli.c */
|
||||
int dnsmgr_init(void); /*!< Provided by dnsmgr.c */
|
||||
void dnsmgr_start_refresh(void); /*!< Provided by dnsmgr.c */
|
||||
int dnsmgr_reload(void); /*!< Provided by dnsmgr.c */
|
||||
void threadstorage_init(void); /*!< Provided by threadstorage.c */
|
||||
|
||||
/* Many headers need 'ast_channel' to be defined */
|
||||
struct ast_channel;
|
||||
|
||||
@@ -365,6 +365,10 @@ void ast_str_reset(struct ast_str *buf),
|
||||
AST_INLINE_API(
|
||||
int ast_str_make_space(struct ast_str **buf, size_t new_len),
|
||||
{
|
||||
#if defined(DEBUG_THREADLOCALS)
|
||||
struct ast_str *old_buf = *buf;
|
||||
#endif /* defined(DEBUG_THREADLOCALS) */
|
||||
|
||||
if (new_len <= (*buf)->len)
|
||||
return 0; /* success */
|
||||
if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC)
|
||||
@@ -372,8 +376,12 @@ int ast_str_make_space(struct ast_str **buf, size_t new_len),
|
||||
*buf = (struct ast_str *)ast_realloc(*buf, new_len + sizeof(struct ast_str));
|
||||
if (*buf == NULL) /* XXX watch out, we leak memory here */
|
||||
return -1;
|
||||
if ((*buf)->ts != DS_MALLOC)
|
||||
if ((*buf)->ts != DS_MALLOC) {
|
||||
pthread_setspecific((*buf)->ts->key, *buf);
|
||||
#if defined(DEBUG_THREADLOCALS)
|
||||
__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));
|
||||
#endif /* defined(DEBUG_THREADLOCALS) */
|
||||
}
|
||||
|
||||
(*buf)->len = new_len;
|
||||
return 0;
|
||||
|
||||
@@ -62,6 +62,12 @@ struct ast_threadstorage {
|
||||
int (*custom_init)(void *); /*!< Custom initialization function specific to the object */
|
||||
};
|
||||
|
||||
#if defined(DEBUG_THREADLOCALS)
|
||||
void __ast_threadstorage_object_add(void *key, size_t len, const char *file, const char *function, unsigned int line);
|
||||
void __ast_threadstorage_object_remove(void *key);
|
||||
void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len);
|
||||
#endif /* defined(DEBUG_THREADLOCALS) */
|
||||
|
||||
/*!
|
||||
* \brief Define a thread storage variable
|
||||
*
|
||||
@@ -93,17 +99,36 @@ struct ast_threadstorage {
|
||||
* AST_THREADSTORAGE_CUSTOM(my_buf, my_init, my_cleanup);
|
||||
* \endcode
|
||||
*/
|
||||
#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
|
||||
static void init_##name(void); \
|
||||
static struct ast_threadstorage name = { \
|
||||
.once = PTHREAD_ONCE_INIT, \
|
||||
.key_init = init_##name, \
|
||||
.custom_init = c_init, \
|
||||
}; \
|
||||
static void init_##name(void) \
|
||||
{ \
|
||||
pthread_key_create(&(name).key, c_cleanup); \
|
||||
#if !defined(DEBUG_THREADLOCALS)
|
||||
#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
|
||||
static void __init_##name(void); \
|
||||
static struct ast_threadstorage name = { \
|
||||
.once = PTHREAD_ONCE_INIT, \
|
||||
.key_init = __init_##name, \
|
||||
.custom_init = c_init, \
|
||||
}; \
|
||||
static void __init_##name(void) \
|
||||
{ \
|
||||
pthread_key_create(&(name).key, c_cleanup); \
|
||||
}
|
||||
#else /* defined(DEBUG_THREADLOCALS) */
|
||||
#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
|
||||
static void __init_##name(void); \
|
||||
static struct ast_threadstorage name = { \
|
||||
.once = PTHREAD_ONCE_INIT, \
|
||||
.key_init = __init_##name, \
|
||||
.custom_init = c_init, \
|
||||
}; \
|
||||
static void __cleanup_##name(void *data) \
|
||||
{ \
|
||||
__ast_threadstorage_object_remove(data); \
|
||||
c_cleanup(data); \
|
||||
} \
|
||||
static void __init_##name(void) \
|
||||
{ \
|
||||
pthread_key_create(&(name).key, __cleanup_##name); \
|
||||
}
|
||||
#endif /* defined(DEBUG_THREADLOCALS) */
|
||||
|
||||
/*!
|
||||
* \brief Retrieve thread storage
|
||||
@@ -135,6 +160,7 @@ static void init_##name(void) \
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
#if !defined(DEBUG_THREADLOCALS)
|
||||
AST_INLINE_API(
|
||||
void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
|
||||
{
|
||||
@@ -154,7 +180,29 @@ void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
|
||||
return buf;
|
||||
}
|
||||
)
|
||||
#else /* defined(DEBUG_THREADLOCALS) */
|
||||
AST_INLINE_API(
|
||||
void *__ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
|
||||
{
|
||||
void *buf;
|
||||
|
||||
void __ast_threadstorage_cleanup(void *);
|
||||
pthread_once(&ts->once, ts->key_init);
|
||||
if (!(buf = pthread_getspecific(ts->key))) {
|
||||
if (!(buf = ast_calloc(1, init_size)))
|
||||
return NULL;
|
||||
if (ts->custom_init && ts->custom_init(buf)) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
pthread_setspecific(ts->key, buf);
|
||||
__ast_threadstorage_object_add(buf, init_size, file, function, line);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
)
|
||||
|
||||
#define ast_threadstorage_get(ts, init_size) __ast_threadstorage_get(ts, init_size, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#endif /* defined(DEBUG_THREADLOCALS) */
|
||||
|
||||
#endif /* ASTERISK_THREADSTORAGE_H */
|
||||
|
||||
Reference in New Issue
Block a user