summaryrefslogtreecommitdiff
path: root/lib/thread.c
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2018-10-01 13:38:34 -0300
committerRafael Zalamena <rzalamena@opensourcerouting.org>2018-10-03 16:32:11 -0300
commitc4345fbf71fcc7ef4b64d95979f252c613dd3ebf (patch)
treef8602546e17376868b00a169e202f6f39b13705c /lib/thread.c
parent6655966d2c2fe7a29ca29af4366fa3e044ad1170 (diff)
lib: refactor thread_execute
Don't allocate threads in the stack, but use the standardized `thread_get` and `thread_add_unused` to avoid creating corner cases in the thread API. This fixes a thread mutex memory leak in FreeBSD. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'lib/thread.c')
-rw-r--r--lib/thread.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/lib/thread.c b/lib/thread.c
index e811bf88c8..f5db6f2421 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -1648,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);
}