aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-16 17:14:01 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-16 17:14:01 +0000
commite5ec2233cef72162696c4e45a7e758e4218a11cb (patch)
treedcb6a2481818394e37619343066de2a1bbcef8ff
parentd23c3140a2376bf26b018476da2ea4e54ae2a25c (diff)
Merged revisions 164736 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r164736 | russell | 2008-12-16 11:06:29 -0600 (Tue, 16 Dec 2008) | 14 lines Fix memory leak and invalid reporting issues with DEBUG_THREADLOCALS. One issue was that the ast_mutex_* API was being used within the context of the thread local data destructors. We would go off and allocate more thread local data while the pthread lib was in the middle of destroying it all. This led to a memory leak. Another issue was an invalid argument being provided to the the object_add API call. (closes issue #13678) Reported by: ys Tested by: Russell ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@164737 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--include/asterisk/threadstorage.h2
-rw-r--r--main/threadstorage.c38
2 files changed, 28 insertions, 12 deletions
diff --git a/include/asterisk/threadstorage.h b/include/asterisk/threadstorage.h
index ab586974f..13b1e007c 100644
--- a/include/asterisk/threadstorage.h
+++ b/include/asterisk/threadstorage.h
@@ -204,7 +204,7 @@ void *__ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size, co
return NULL;
}
pthread_setspecific(ts->key, buf);
- __ast_threadstorage_object_add(&ts->key, init_size, file, function, line);
+ __ast_threadstorage_object_add(buf, init_size, file, function, line);
}
return buf;
diff --git a/main/threadstorage.c b/main/threadstorage.c
index 94ea45d4e..a54ffac7a 100644
--- a/main/threadstorage.c
+++ b/main/threadstorage.c
@@ -53,8 +53,23 @@ struct tls_object {
};
static AST_LIST_HEAD_NOLOCK_STATIC(tls_objects, tls_object);
-AST_MUTEX_DEFINE_STATIC_NOTRACKING(threadstoragelock);
+/* Allow direct use of pthread_mutex_t and friends */
+#undef pthread_mutex_t
+#undef pthread_mutex_lock
+#undef pthread_mutex_unlock
+#undef pthread_mutex_init
+#undef pthread_mutex_destroy
+
+/*!
+ * \brief lock for the tls_objects list
+ *
+ * \note We can not use an ast_mutex_t for this. The reason is that this
+ * lock is used within the context of thread-local data destructors,
+ * and the ast_mutex_* API uses thread-local data. Allocating more
+ * thread-local data at that point just causes a memory leak.
+ */
+static pthread_mutex_t threadstoragelock;
void __ast_threadstorage_object_add(void *key, size_t len, const char *file, const char *function, unsigned int line)
{
@@ -70,16 +85,16 @@ void __ast_threadstorage_object_add(void *key, size_t len, const char *file, con
to->line = line;
to->thread = pthread_self();
- ast_mutex_lock(&threadstoragelock);
+ pthread_mutex_lock(&threadstoragelock);
AST_LIST_INSERT_TAIL(&tls_objects, to, entry);
- ast_mutex_unlock(&threadstoragelock);
+ pthread_mutex_unlock(&threadstoragelock);
}
void __ast_threadstorage_object_remove(void *key)
{
struct tls_object *to;
- ast_mutex_lock(&threadstoragelock);
+ pthread_mutex_lock(&threadstoragelock);
AST_LIST_TRAVERSE_SAFE_BEGIN(&tls_objects, to, entry) {
if (to->key == key) {
AST_LIST_REMOVE_CURRENT(entry);
@@ -87,7 +102,7 @@ void __ast_threadstorage_object_remove(void *key)
}
}
AST_LIST_TRAVERSE_SAFE_END;
- ast_mutex_unlock(&threadstoragelock);
+ pthread_mutex_unlock(&threadstoragelock);
if (to)
ast_free(to);
}
@@ -96,7 +111,7 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len
{
struct tls_object *to;
- ast_mutex_lock(&threadstoragelock);
+ pthread_mutex_lock(&threadstoragelock);
AST_LIST_TRAVERSE_SAFE_BEGIN(&tls_objects, to, entry) {
if (to->key == key_old) {
to->key = key_new;
@@ -105,7 +120,7 @@ void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len
}
}
AST_LIST_TRAVERSE_SAFE_END;
- ast_mutex_unlock(&threadstoragelock);
+ pthread_mutex_unlock(&threadstoragelock);
}
static char *handle_cli_threadstorage_show_allocations(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
@@ -133,7 +148,7 @@ static char *handle_cli_threadstorage_show_allocations(struct ast_cli_entry *e,
if (a->argc > 3)
fn = a->argv[3];
- ast_mutex_lock(&threadstoragelock);
+ pthread_mutex_lock(&threadstoragelock);
AST_LIST_TRAVERSE(&tls_objects, to, entry) {
if (fn && strcasecmp(to->file, fn))
@@ -145,7 +160,7 @@ static char *handle_cli_threadstorage_show_allocations(struct ast_cli_entry *e,
count++;
}
- ast_mutex_unlock(&threadstoragelock);
+ pthread_mutex_unlock(&threadstoragelock);
ast_cli(a->fd, "%10d bytes allocated in %d allocation%s\n", (int) len, count, count > 1 ? "s" : "");
@@ -184,7 +199,7 @@ static char *handle_cli_threadstorage_show_summary(struct ast_cli_entry *e, int
if (a->argc > 3)
fn = a->argv[3];
- ast_mutex_lock(&threadstoragelock);
+ pthread_mutex_lock(&threadstoragelock);
AST_LIST_TRAVERSE(&tls_objects, to, entry) {
if (fn && strcasecmp(to->file, fn))
@@ -206,7 +221,7 @@ static char *handle_cli_threadstorage_show_summary(struct ast_cli_entry *e, int
file->count++;
}
- ast_mutex_unlock(&threadstoragelock);
+ pthread_mutex_unlock(&threadstoragelock);
AST_LIST_TRAVERSE(&file_summary, file, entry) {
len += file->len;
@@ -232,6 +247,7 @@ static struct ast_cli_entry cli[] = {
void threadstorage_init(void)
{
+ pthread_mutex_init(&threadstoragelock, NULL);
ast_cli_register_multiple(cli, ARRAY_LEN(cli));
}