Crash in CATerminate 64/181764/1
authorVeeraj Khokale <veeraj.sk@samsung.com>
Thu, 7 Jun 2018 13:30:59 +0000 (19:00 +0530)
committerAmit KS <amit.s12@samsung.com>
Mon, 18 Jun 2018 06:43:35 +0000 (12:13 +0530)
The variable caglobals.tcp.terminate is used to signal the
receiver thread to stop. However using a volatile variable
to synchronize between threads is undefined behaviour as
per the C/C++ standards. In this particular case due to
cache coherence behaviour on SMP mobile(especially ARM)
multi core processors, the receiver thread is not guaranteed
to see the change to the terminate variable as soon as
adapter is terminated and this delay could cause an ANR.

https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/290
(cherry picked from commit 38101be161271b68cee847748d71fb4ded73bc5a)

Change-Id: Ied3fbb138fe095a1e4a9eb51016e59c2be5730e5
Signed-off-by: Veeraj Khokale <veeraj.sk@samsung.com>
Signed-off-by: Amit KS <amit.s12@samsung.com>
resource/csdk/connectivity/src/tcp_adapter/catcpserver.c

index a1572c09174b5f6653162950f22c966d73b98f5a..7cf9a7152ba9bd87dcfc1b2112816b0496989de7 100644 (file)
@@ -245,8 +245,15 @@ static void CAReceiveHandler(void *data)
     (void)data;
     OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler");
 
-    while (!caglobals.tcp.terminate)
+    while (true)
     {
+        oc_mutex_lock(g_mutexObjectList);
+        if (caglobals.tcp.terminate)
+        {
+            oc_mutex_unlock(g_mutexObjectList);
+            break;
+        }
+        oc_mutex_unlock(g_mutexObjectList);
         CAFindReadyMessage();
     }
 
@@ -291,11 +298,14 @@ static void CAFindReadyMessage()
 
     int ret = select(caglobals.tcp.maxfd + 1, &readFds, NULL, NULL, &timeout);
 
+    oc_mutex_lock(g_mutexObjectList);
     if (caglobals.tcp.terminate)
     {
+        oc_mutex_unlock(g_mutexObjectList);
         OIC_LOG_V(INFO, TAG, "Packet receiver Stop request received.");
         return;
     }
+    oc_mutex_unlock(g_mutexObjectList);
     if (0 >= ret)
     {
         if (0 > ret)
@@ -1288,10 +1298,13 @@ static ssize_t sendData(const CAEndpoint_t *endpoint, const void *data,
             oc_cond_wait_for(g_condSend, g_mutexSend, waitTime);
             oc_mutex_unlock(g_mutexSend);
 
+            oc_mutex_lock(g_mutexObjectList);
             if (caglobals.tcp.terminate)
             {
+                oc_mutex_unlock(g_mutexObjectList);
                 return len;
             }
+            oc_mutex_unlock(g_mutexObjectList);
 
             sendRetryTime = (sendRetryTime << 1);