summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
29c1fca)
g_sendQueueHandle is set to NULL to prevent new requests from being enqueued.
It avoids a race condition which could occur when adding elements to QueueingThread if it's already stopped.
Race condition scenario:-
Background:-
-> If a thread has called CAQueueingThreadStop(), it signals the condition variable
to wake up the CAQueueingThreadBaseRoutine.
-> After signaling, it waits on the same condition variable
to wait for the completion of CAQueueingThreadBaseRoutine.
-> CAQueueingThreadBaseRoutine will finish its current task and signals the condition variable.
-> CAQueueingThreadStop should wake up upon signal and return back to caller.
Issue:-
-> CAQueueingThreadAddData also signals the condition variable which can wake up the thread that called CAQueueingThreadStop.
-> CAQueueingThreadStop returns back to caller assuming that the CAQueueingThreadBaseRoutine has stopped. But it could still be running.
https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/525
(cherry picked from
eb98e19b49ab4d4475449f99f3a4a53607dbea01)
Change-Id: I5b22c034b30b00fc1ae7f08c37c278c29910345c
Signed-off-by: Senthil Kumar G S <senthil.gs@samsung.com>
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
static CAResult_t CATCPInitializeQueueHandles();
static CAResult_t CATCPInitializeQueueHandles();
-static void CATCPDeinitializeQueueHandles();
+static void CATCPDeinitializeQueueHandles(CAQueueingThread_t *queueHandle);
static void CATCPSendDataThread(void *threadData);
static void CATCPSendDataThread(void *threadData);
-void CATCPDeinitializeQueueHandles()
+void CATCPDeinitializeQueueHandles(CAQueueingThread_t *queueHandle)
- CAQueueingThreadDestroy(g_sendQueueHandle);
- OICFree(g_sendQueueHandle);
- g_sendQueueHandle = NULL;
+ CAQueueingThreadDestroy(queueHandle);
+ OICFree(queueHandle);
}
void CATCPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
}
void CATCPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
#ifndef SINGLE_THREAD
// Stop send queue thread.
#ifndef SINGLE_THREAD
// Stop send queue thread.
- if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
+ if (g_sendQueueHandle != NULL)
- CAQueueingThreadStop(g_sendQueueHandle);
+ // g_sendQueueHandle is set to NULL to prevent new requests from being enqueued.
+ CAQueueingThread_t *queueHandle = g_sendQueueHandle;
+ g_sendQueueHandle = NULL;
+
+ if (queueHandle->threadMutex)
+ {
+ CAQueueingThreadStop(queueHandle);
+ }
+ CATCPDeinitializeQueueHandles(queueHandle);
- CATCPDeinitializeQueueHandles();
#endif
// Close TCP servers and established connections.
#endif
// Close TCP servers and established connections.