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

Reply via email to