diff options
| author | Quentin Young <qlyoung@users.noreply.github.com> | 2018-10-03 18:43:34 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-10-03 18:43:34 -0400 |
| commit | 56f67d6870c6ab2c41b07c9a81874bcfd4a3e4f2 (patch) | |
| tree | 080af23c552ab8de22228384b97587f196a48d5b /lib/thread.c | |
| parent | 139221f25051db7a52ac64fed418d19125b7c3ae (diff) | |
| parent | c4345fbf71fcc7ef4b64d95979f252c613dd3ebf (diff) | |
Merge pull request #3087 from opensourcerouting/bfd-memleak
bfdd: fix memory leak and echo-mode start
Diffstat (limited to 'lib/thread.c')
| -rw-r--r-- | lib/thread.c | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/lib/thread.c b/lib/thread.c index a81faae796..267dcd1cfc 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -58,6 +58,7 @@ pthread_key_t thread_current; pthread_mutex_t masters_mtx = PTHREAD_MUTEX_INITIALIZER; static struct list *masters; +static void thread_free(struct thread_master *master, struct thread *thread); /* CLI start ---------------------------------------------------------------- */ static unsigned int cpu_record_hash_key(struct cpu_thread_history *a) @@ -538,6 +539,8 @@ static struct thread *thread_trim_head(struct thread_list *list) /* Move thread to unuse list. */ static void thread_add_unuse(struct thread_master *m, struct thread *thread) { + pthread_mutex_t mtxc = thread->mtx; + assert(m != NULL && thread != NULL); assert(thread->next == NULL); assert(thread->prev == NULL); @@ -546,10 +549,15 @@ static void thread_add_unuse(struct thread_master *m, struct thread *thread) memset(thread, 0, sizeof(struct thread)); thread->type = THREAD_UNUSED; - if (m->unuse.count < THREAD_UNUSED_DEPTH) + /* Restore the thread mutex context. */ + thread->mtx = mtxc; + + if (m->unuse.count < THREAD_UNUSED_DEPTH) { thread_list_add(&m->unuse, thread); - else - XFREE(MTYPE_THREAD, thread); + return; + } + + thread_free(m, thread); } /* Free all unused thread. */ @@ -560,9 +568,8 @@ static void thread_list_free(struct thread_master *m, struct thread_list *list) for (t = list->head; t; t = next) { next = t->next; - XFREE(MTYPE_THREAD, t); + thread_free(m, t); list->count--; - m->alloc--; } } @@ -576,8 +583,7 @@ static void thread_array_free(struct thread_master *m, t = thread_array[index]; if (t) { thread_array[index] = NULL; - XFREE(MTYPE_THREAD, t); - m->alloc--; + thread_free(m, t); } } XFREE(MTYPE_THREAD_POLL, thread_array); @@ -588,9 +594,8 @@ static void thread_queue_free(struct thread_master *m, struct pqueue *queue) int i; for (i = 0; i < queue->size; i++) - XFREE(MTYPE_THREAD, queue->array[i]); + thread_free(m, queue->array[i]); - m->alloc -= queue->size; pqueue_delete(queue); } @@ -608,8 +613,7 @@ void thread_master_free_unused(struct thread_master *m) { struct thread *t; while ((t = thread_trim_head(&m->unuse)) != NULL) { - pthread_mutex_destroy(&t->mtx); - XFREE(MTYPE_THREAD, t); + thread_free(m, t); } } pthread_mutex_unlock(&m->mtx); @@ -728,6 +732,17 @@ static struct thread *thread_get(struct thread_master *m, uint8_t type, return thread; } +static void thread_free(struct thread_master *master, struct thread *thread) +{ + /* Update statistics. */ + assert(master->alloc > 0); + master->alloc--; + + /* Free allocated resources. */ + pthread_mutex_destroy(&thread->mtx); + XFREE(MTYPE_THREAD, thread); +} + static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize, nfds_t count, const struct timeval *timer_wait) { @@ -1633,25 +1648,27 @@ void funcname_thread_execute(struct thread_master *m, int (*func)(struct thread *), void *arg, int val, debugargdef) { - struct cpu_thread_history tmp; - struct thread dummy; - - memset(&dummy, 0, sizeof(struct thread)); + struct thread *thread; - pthread_mutex_init(&dummy.mtx, NULL); - dummy.type = THREAD_EVENT; - dummy.add_type = THREAD_EXECUTE; - dummy.master = NULL; - dummy.arg = arg; - dummy.u.val = val; + /* Get or allocate new thread to execute. */ + pthread_mutex_lock(&m->mtx); + { + thread = thread_get(m, THREAD_EVENT, func, arg, debugargpass); - tmp.func = dummy.func = func; - tmp.funcname = dummy.funcname = funcname; - dummy.hist = hash_get(m->cpu_record, &tmp, - (void *(*)(void *))cpu_record_hash_alloc); + /* Set its event value. */ + pthread_mutex_lock(&thread->mtx); + { + thread->add_type = THREAD_EXECUTE; + thread->u.val = val; + thread->ref = &thread; + } + pthread_mutex_unlock(&thread->mtx); + } + pthread_mutex_unlock(&m->mtx); - dummy.schedfrom = schedfrom; - dummy.schedfrom_line = fromln; + /* Execute thread doing all accounting. */ + thread_call(thread); - thread_call(&dummy); + /* Give back or free thread. */ + thread_add_unuse(m, thread); } |
