Fixed a pair of deadlocks on shutdown
authorErich Keane <erich.keane@intel.com>
Thu, 30 Apr 2015 16:32:12 +0000 (09:32 -0700)
committerErich Keane <erich.keane@intel.com>
Fri, 1 May 2015 17:40:38 +0000 (17:40 +0000)
In the event where a condition variable was signaled before it
was waited on, the thread would fail to exit properly and be
deadlocked.

This fix correctly checks the stop value before locking, and ensures
that signalling is done in a locked context as well.

Change-Id: Iab19adcee854a1ca1531deea29fa3bb6c82d042f
Signed-off-by: Erich Keane <erich.keane@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/874
Reviewed-by: Joseph Morrow <joseph.l.morrow@intel.com>
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
resource/csdk/connectivity/src/caqueueingthread.c
resource/csdk/connectivity/src/caretransmission.c

index 9f8a97a..01bed4b 100644 (file)
@@ -50,7 +50,7 @@ static void CAQueueingThreadBaseRoutine(void *threadValue)
         ca_mutex_lock(thread->threadMutex);
 
         // if queue is empty, thread will wait
-        if (u_queue_get_size(thread->dataQueue) <= 0)
+        if (!thread->isStop && u_queue_get_size(thread->dataQueue) <= 0)
         {
             OIC_LOG(DEBUG, TAG, "wait..");
 
@@ -114,7 +114,9 @@ static void CAQueueingThreadBaseRoutine(void *threadValue)
         }
     }
 
+    ca_mutex_lock(thread->threadMutex);
     ca_cond_signal(thread->threadCond);
+    ca_mutex_unlock(thread->threadMutex);
 
     OIC_LOG(DEBUG, TAG, "message handler main thread end..");
 }
index e10fa17..e4938f5 100644 (file)
@@ -214,7 +214,7 @@ static void CARetransmissionBaseRoutine(void *threadValue)
         // mutex lock
         ca_mutex_lock(context->threadMutex);
 
-        if (u_arraylist_length(context->dataList) <= 0)
+        if (!context->isStop && u_arraylist_length(context->dataList) <= 0)
         {
             // if list is empty, thread will wait
             OIC_LOG(DEBUG, TAG, "wait..there is no retransmission data.");
@@ -247,7 +247,9 @@ static void CARetransmissionBaseRoutine(void *threadValue)
         CACheckRetransmissionList(context);
     }
 
+    ca_mutex_lock(context->threadMutex);
     ca_cond_signal(context->threadCond);
+    ca_mutex_unlock(context->threadMutex);
 
     OIC_LOG(DEBUG, TAG, "retransmission main thread end..");