From 1dcc1591c3e1f6ab0fe56849dc3424dca2a8df26 Mon Sep 17 00:00:00 2001 From: Veeraj Khokale Date: Thu, 7 Jun 2018 19:00:59 +0530 Subject: [PATCH] Crash in CATerminate 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: Ib18b91b9efde71d4075c0ec9c9639ac8051df6b6 Signed-off-by: Veeraj Khokale Signed-off-by: Amit KS --- resource/csdk/connectivity/src/tcp_adapter/catcpserver.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c index a1572c0..7cf9a71 100644 --- a/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c +++ b/resource/csdk/connectivity/src/tcp_adapter/catcpserver.c @@ -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); -- 2.7.4