[ofa-general] [PATCH] dapl v2: common: no cleanup/release code for timer thread

Davis, Arlin R arlin.r.davis at intel.com
Thu Sep 17 11:32:16 PDT 2009


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.davis at 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




More information about the general mailing list