From bf5c0ce8d90613a39df2f6fec79071250b79d1d1 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 4 Apr 2017 17:51:22 +0200 Subject: ipcpd, irmd: Fix cleanup of thread resources --- src/ipcpd/ipcp.c | 39 ++++++++++++++++----------------------- src/irmd/main.c | 40 +++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index ee5bd76e..fc0e3587 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -522,27 +522,19 @@ int ipcp_init(int argc, return 0; } -static bool is_thread_alive(ssize_t id) -{ - bool ret; - pthread_mutex_lock(&ipcpi.threads_lock); - - ret = bmp_is_id_used(ipcpi.thread_ids, id); - - pthread_mutex_unlock(&ipcpi.threads_lock); - - return ret; -} - void * threadpoolmgr(void * o) { - struct timespec to = {(IPCP_TPM_TIMEOUT / 1000), - (IPCP_TPM_TIMEOUT % 1000) * MILLION}; + pthread_attr_t pattr; struct timespec dl; - size_t t; - + struct timespec to = {(IRMD_TPM_TIMEOUT / 1000), + (IRMD_TPM_TIMEOUT % 1000) * MILLION}; (void) o; + if (pthread_attr_init(&pattr)) + return (void *) -1; + + pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); + while (true) { clock_gettime(PTHREAD_COND_CLOCK, &dl); ts_add(&dl, &to, &dl); @@ -551,12 +543,13 @@ void * threadpoolmgr(void * o) if (ipcp_get_state() == IPCP_SHUTDOWN || ipcp_get_state() == IPCP_NULL) { pthread_rwlock_unlock(&ipcpi.state_lock); - log_dbg("Threadpool manager exiting."); - for (t = 0; t < IPCP_MAX_THREADS; ++t) - if (is_thread_alive(t)) { - log_dbg("Waiting for thread %zd.", t); - pthread_join(ipcpi.threadpool[t], NULL); - } + pthread_attr_destroy(&pattr); + log_dbg("Waiting for threads to exit."); + pthread_mutex_lock(&ipcpi.threads_lock); + while (ipcpi.threads > 0) + pthread_cond_wait(&ipcpi.threads_cond, + &ipcpi.threads_lock); + pthread_mutex_unlock(&ipcpi.threads_lock); log_dbg("Threadpool manager done."); break; @@ -578,7 +571,7 @@ void * threadpoolmgr(void * o) } if (pthread_create(&ipcpi.threadpool[id], - NULL, ipcp_main_loop, + &pattr, ipcp_main_loop, (void *) id)) log_warn("Failed to start new thread."); else diff --git a/src/irmd/main.c b/src/irmd/main.c index e6647285..fa58e218 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -1815,6 +1815,7 @@ void * mainloop(void * o) if (irmd->state != IRMD_RUNNING || thread_check()) { thread_exit(id); pthread_rwlock_unlock(&irmd->state_lock); + log_dbg("Thread %zd exited.", id); break; } @@ -2009,27 +2010,19 @@ void * mainloop(void * o) return (void *) 0; } -static bool is_thread_alive(ssize_t id) -{ - bool ret; - pthread_mutex_lock(&irmd->threads_lock); - - ret = bmp_is_id_used(irmd->thread_ids, id); - - pthread_mutex_unlock(&irmd->threads_lock); - - return ret; -} - void * threadpoolmgr(void * o) { + pthread_attr_t pattr; + struct timespec dl; struct timespec to = {(IRMD_TPM_TIMEOUT / 1000), (IRMD_TPM_TIMEOUT % 1000) * MILLION}; - struct timespec dl; - size_t t; - (void) o; + if (pthread_attr_init(&pattr)) + return (void *) -1; + + pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED); + while (true) { clock_gettime(PTHREAD_COND_CLOCK, &dl); ts_add(&dl, &to, &dl); @@ -2037,13 +2030,13 @@ void * threadpoolmgr(void * o) pthread_rwlock_rdlock(&irmd->state_lock); if (irmd->state != IRMD_RUNNING) { pthread_rwlock_unlock(&irmd->state_lock); - log_dbg("Threadpool manager exiting."); - for (t = 0; t < IRMD_MAX_THREADS; ++t) - if (is_thread_alive(t)) { - log_dbg("Waiting for thread %zd.", t); - pthread_join(irmd->threadpool[t], NULL); - } - + pthread_attr_destroy(&pattr); + log_dbg("Waiting for threads exit."); + pthread_mutex_lock(&irmd->threads_lock); + while (irmd->threads > 0) + pthread_cond_wait(&irmd->threads_cond, + &irmd->threads_lock); + pthread_mutex_unlock(&irmd->threads_lock); log_dbg("Threadpool manager done."); break; } @@ -2064,7 +2057,8 @@ void * threadpoolmgr(void * o) } if (pthread_create(&irmd->threadpool[id], - NULL, mainloop, (void *) id)) + &pattr, mainloop, + (void *) id)) log_warn("Failed to start new thread."); else ++irmd->threads; -- cgit v1.2.3