dapl_set_timer() creates a thread to process timers for dat_ep_connect but provides no mechanism to destroy/exit during dapl library unload. Timers are initialized in library init code and should be released in the fini code. Add a dapl_timer_release call to the dapl_fini function to check state of timer thread and destroy before exiting.
Signed-off-by: Arlin Davis <arlin.r.da...@intel.com> --- dapl/common/dapl_timer_util.c | 48 ++++++++++++++++++++++++++++++++++++++++- dapl/common/dapl_timer_util.h | 1 + dapl/udapl/dapl_init.c | 1 + 3 files changed, 49 insertions(+), 1 deletions(-) diff --git a/dapl/common/dapl_timer_util.c b/dapl/common/dapl_timer_util.c index f0d7964..cccaff1 100644 --- a/dapl/common/dapl_timer_util.c +++ b/dapl/common/dapl_timer_util.c @@ -52,11 +52,17 @@ #include "dapl.h" #include "dapl_timer_util.h" +#define DAPL_TIMER_INIT 0 +#define DAPL_TIMER_RUN 1 +#define DAPL_TIMER_DESTROY 2 +#define DAPL_TIMER_EXIT 3 + struct timer_head { DAPL_LLIST_HEAD timer_list_head; DAPL_OS_LOCK lock; DAPL_OS_WAIT_OBJECT wait_object; DAPL_OS_THREAD timeout_thread_handle; + int state; } g_daplTimerHead; typedef struct timer_head DAPL_TIMER_HEAD; @@ -73,6 +79,23 @@ void dapls_timer_init() dapl_os_lock_init(&g_daplTimerHead.lock); dapl_os_wait_object_init(&g_daplTimerHead.wait_object); g_daplTimerHead.timeout_thread_handle = 0; + g_daplTimerHead.state = DAPL_TIMER_INIT; +} + +void dapls_timer_release() +{ + dapl_os_lock(&g_daplTimerHead.lock); + if (g_daplTimerHead.state != DAPL_TIMER_RUN) { + dapl_os_unlock(&g_daplTimerHead.lock); + return; + } + + g_daplTimerHead.state = DAPL_TIMER_DESTROY; + dapl_os_unlock(&g_daplTimerHead.lock); + while (g_daplTimerHead.state != DAPL_TIMER_EXIT) { + dapl_os_wait_object_wakeup(&g_daplTimerHead.wait_object); + dapl_os_sleep_usec(2000); + } } /* @@ -107,6 +130,9 @@ dapls_timer_set(IN DAPL_OS_TIMER * timer, dapl_os_thread_create(dapls_timer_thread, &g_daplTimerHead, &g_daplTimerHead.timeout_thread_handle); + + while (g_daplTimerHead.state != DAPL_TIMER_RUN) + dapl_os_sleep_usec(2000); } dapl_llist_init_entry(&timer->list_entry); @@ -121,6 +147,12 @@ dapls_timer_set(IN DAPL_OS_TIMER * timer, * first. */ dapl_os_lock(&g_daplTimerHead.lock); + + if (g_daplTimerHead.state != DAPL_TIMER_RUN) { + dapl_os_unlock(&g_daplTimerHead.lock); + return DAT_INVALID_STATE; + } + /* * Deal with 3 cases due to our list structure: * 1) list is empty: become the list head @@ -246,6 +278,10 @@ void dapls_timer_thread(void *arg) timer_head = arg; + dapl_os_lock(&timer_head->lock); + timer_head->state = DAPL_TIMER_RUN; + dapl_os_unlock(&timer_head->lock); + for (;;) { if (dapl_llist_is_empty(&timer_head->timer_list_head)) { dat_status = @@ -265,7 +301,9 @@ void dapls_timer_thread(void *arg) timer_list_head); dapl_os_get_time(&cur_time); - if (list_ptr->expires <= cur_time) { + if (list_ptr->expires <= cur_time || + timer_head->state == DAPL_TIMER_DESTROY) { + /* * Remove the entry from the list. Sort out how much * time we need to sleep for the next one @@ -297,6 +335,14 @@ void dapls_timer_thread(void *arg) dapl_os_lock(&timer_head->lock); } } + + /* Destroy - all timers triggered and list is empty */ + if (timer_head->state == DAPL_TIMER_DESTROY) { + timer_head->state = DAPL_TIMER_EXIT; + dapl_os_unlock(&timer_head->lock); + break; + } + /* * release the lock before going back to the top to sleep */ diff --git a/dapl/common/dapl_timer_util.h b/dapl/common/dapl_timer_util.h index c24d26a..02f7069 100644 --- a/dapl/common/dapl_timer_util.h +++ b/dapl/common/dapl_timer_util.h @@ -36,6 +36,7 @@ **********************************************************************/ void dapls_timer_init ( void ); +void dapls_timer_release( void ); DAT_RETURN dapls_timer_set ( IN DAPL_OS_TIMER *timer, diff --git a/dapl/udapl/dapl_init.c b/dapl/udapl/dapl_init.c index e0af8f7..a889ffb 100644 --- a/dapl/udapl/dapl_init.c +++ b/dapl/udapl/dapl_init.c @@ -151,6 +151,7 @@ void dapl_fini(void) } dapls_ib_release(); + dapls_timer_release(); dapl_dbg_log(DAPL_DBG_TYPE_UTIL, "DAPL: Exit (dapl_fini)\n"); -- 1.5.2.5 _______________________________________________ general mailing list general@lists.openfabrics.org http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general