diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-01-04 23:18:36 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-01-04 23:18:36 +0000 |
commit | cdcfae52305bc229a9e500857904b945ead2aaad (patch) | |
tree | 7a611d8d292ad6f75bb7d77e5a3348a76706f30f /include | |
parent | ae60d026a05a6b63a9544d9bc545533a167c00c9 (diff) |
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: http://svn.digium.com/svn/asterisk/trunk@49578 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r-- | include/asterisk.h | 1 | ||||
-rw-r--r-- | include/asterisk/strings.h | 10 | ||||
-rw-r--r-- | include/asterisk/threadstorage.h | 70 |
3 files changed, 69 insertions, 12 deletions
diff --git a/include/asterisk.h b/include/asterisk.h index 7bbb75f3a..52db3b91f 100644 --- a/include/asterisk.h +++ b/include/asterisk.h @@ -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; diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h index f79e9b2fe..53486d1b0 100644 --- a/include/asterisk/strings.h +++ b/include/asterisk/strings.h @@ -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; diff --git a/include/asterisk/threadstorage.h b/include/asterisk/threadstorage.h index 469f46389..442101113 100644 --- a/include/asterisk/threadstorage.h +++ b/include/asterisk/threadstorage.h @@ -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; + + 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; +} +) -void __ast_threadstorage_cleanup(void *); +#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 */ |