From 2749ff9dff85a4d035630f17668819d86de86cbe Mon Sep 17 00:00:00 2001 From: "hyuna0213.jo" Date: Wed, 30 Nov 2016 13:29:36 +0900 Subject: [PATCH] [IOT-1625] Fix a logic to terminate CA in case of failure of init - If CAInitializeMessageHandler() fails, we should call CATerminateMessageHandler() to terminate the main thread successfully. - Calling u_arraylist_reserve before creating the thread Bug: https://jira.iotivity.org/browse/IOT-1625 Change-Id: If291d90bbe69abbf967a7f0014c6e5d44644131d Signed-off-by: hyuna0213.jo Reviewed-on: https://gerrit.iotivity.org/gerrit/14941 Reviewed-by: Dan Mihai Tested-by: jenkins-iotivity Reviewed-by: Dave Thaler Reviewed-by: Jaewook Jung Reviewed-by: Jaehong Jo Reviewed-by: Ashok Babu Channa Reviewed-by: Uze Choi Reviewed-on: https://gerrit.iotivity.org/gerrit/15327 Reviewed-by: jihwan seo --- resource/csdk/connectivity/common/inc/uarraylist.h | 3 ++- .../common/src/cathreadpool_pthreads.c | 18 +++++++++++++-- resource/csdk/connectivity/common/src/uarraylist.c | 5 +++-- .../csdk/connectivity/src/caconnectivitymanager.c | 1 + resource/csdk/connectivity/src/camessagehandler.c | 26 ---------------------- resource/csdk/connectivity/src/caqueueingthread.c | 8 +++++-- 6 files changed, 28 insertions(+), 33 deletions(-) diff --git a/resource/csdk/connectivity/common/inc/uarraylist.h b/resource/csdk/connectivity/common/inc/uarraylist.h index 31a70f6..c3eb90b 100644 --- a/resource/csdk/connectivity/common/inc/uarraylist.h +++ b/resource/csdk/connectivity/common/inc/uarraylist.h @@ -68,8 +68,9 @@ void u_arraylist_free(u_arraylist_t **list); * entries. * @param list the list to operate on. * @param count the size to attempt to reserve room for. + * @return true if success, false otherwise. */ -void u_arraylist_reserve(u_arraylist_t *list, size_t count); +bool u_arraylist_reserve(u_arraylist_t *list, size_t count); /** * Request that the storage in the list be reduced to fit its current length. diff --git a/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c b/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c index e9dfb18..624101a 100644 --- a/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c +++ b/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c @@ -159,22 +159,36 @@ CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func info->func = method; info->data = data; + oc_mutex_lock(thread_pool->details->list_lock); + if (thread_pool->details->threads_list->capacity <= thread_pool->details->threads_list->length) + { + size_t new_capacity = ((thread_pool->details->threads_list->capacity * 3) + 1) / 2; + bool reserveResult = u_arraylist_reserve(thread_pool->details->threads_list, new_capacity); + if (!reserveResult) + { + oc_mutex_unlock(thread_pool->details->list_lock); + OIC_LOG(ERROR, TAG, "Arraylist reserve failed"); + return CA_STATUS_FAILED; + } + } + oc_thread thread; int thrRet = oc_thread_new(&thread, ca_thread_pool_pthreads_delegate, info); if (thrRet != 0) { + oc_mutex_unlock(thread_pool->details->list_lock); OIC_LOG_V(ERROR, TAG, "Thread start failed with error %d", thrRet); OICFree(info); return CA_STATUS_FAILED; } - oc_mutex_lock(thread_pool->details->list_lock); bool addResult = u_arraylist_add(thread_pool->details->threads_list, (void*)thread); oc_mutex_unlock(thread_pool->details->list_lock); if(!addResult) { - OIC_LOG_V(ERROR, TAG, "Arraylist Add failed, may not be properly joined: %d", addResult); + // Note that this is considered non-fatal. + OIC_LOG(ERROR, TAG, "Arraylist add failed"); oc_thread_free(thread); return CA_STATUS_FAILED; } diff --git a/resource/csdk/connectivity/common/src/uarraylist.c b/resource/csdk/connectivity/common/src/uarraylist.c index 13b2a2c..f7ff470 100644 --- a/resource/csdk/connectivity/common/src/uarraylist.c +++ b/resource/csdk/connectivity/common/src/uarraylist.c @@ -66,7 +66,7 @@ void u_arraylist_free(u_arraylist_t **list) *list = NULL; } -void u_arraylist_reserve(u_arraylist_t *list, size_t count) +bool u_arraylist_reserve(u_arraylist_t *list, size_t count) { if (list && (count > list->capacity)) { @@ -74,7 +74,7 @@ void u_arraylist_reserve(u_arraylist_t *list, size_t count) if (!tmp) { OIC_LOG(DEBUG, TAG, "Memory reallocation failed."); - // Note that this is considered non-fatal. + return false; } else { @@ -82,6 +82,7 @@ void u_arraylist_reserve(u_arraylist_t *list, size_t count) list->capacity = count; } } + return true; } void u_arraylist_shrink_to_fit(u_arraylist_t *list) diff --git a/resource/csdk/connectivity/src/caconnectivitymanager.c b/resource/csdk/connectivity/src/caconnectivitymanager.c index a5dbf2b..8e0d55c 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager.c @@ -71,6 +71,7 @@ CAResult_t CAInitialize() if (res != CA_STATUS_OK) { OIC_LOG(ERROR, TAG, "CAInitialize has failed"); + CATerminateMessageHandler(); return res; } g_isInitialized = true; diff --git a/resource/csdk/connectivity/src/camessagehandler.c b/resource/csdk/connectivity/src/camessagehandler.c index 1f3fe86..f5bbec4 100644 --- a/resource/csdk/connectivity/src/camessagehandler.c +++ b/resource/csdk/connectivity/src/camessagehandler.c @@ -1066,8 +1066,6 @@ CAResult_t CAInitializeMessageHandler() if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread"); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; return res; } @@ -1076,9 +1074,6 @@ CAResult_t CAInitializeMessageHandler() if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread start error(send thread)."); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; - CAQueueingThreadDestroy(&g_sendThread); return res; } @@ -1088,9 +1083,6 @@ CAResult_t CAInitializeMessageHandler() if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "Failed to Initialize receive queue thread"); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; - CAQueueingThreadDestroy(&g_sendThread); return res; } @@ -1100,10 +1092,6 @@ CAResult_t CAInitializeMessageHandler() if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread start error(receive thread)."); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; - CAQueueingThreadDestroy(&g_sendThread); - CAQueueingThreadDestroy(&g_receiveThread); return res; } #endif // SINGLE_HANDLE @@ -1114,10 +1102,6 @@ CAResult_t CAInitializeMessageHandler() if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "Failed to Initialize Retransmission."); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; - CAQueueingThreadDestroy(&g_sendThread); - CAQueueingThreadDestroy(&g_receiveThread); return res; } @@ -1127,11 +1111,6 @@ CAResult_t CAInitializeMessageHandler() if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "Failed to Initialize BlockWiseTransfer."); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; - CAQueueingThreadDestroy(&g_sendThread); - CAQueueingThreadDestroy(&g_receiveThread); - CARetransmissionDestroy(&g_retransmissionContext); return res; } #endif @@ -1141,11 +1120,6 @@ CAResult_t CAInitializeMessageHandler() if (CA_STATUS_OK != res) { OIC_LOG(ERROR, TAG, "thread start error(retransmission thread)."); - ca_thread_pool_free(g_threadPoolHandle); - g_threadPoolHandle = NULL; - CAQueueingThreadDestroy(&g_sendThread); - CAQueueingThreadDestroy(&g_receiveThread); - CARetransmissionDestroy(&g_retransmissionContext); return res; } diff --git a/resource/csdk/connectivity/src/caqueueingthread.c b/resource/csdk/connectivity/src/caqueueingthread.c index cf28c7d..22ae5d8 100644 --- a/resource/csdk/connectivity/src/caqueueingthread.c +++ b/resource/csdk/connectivity/src/caqueueingthread.c @@ -181,9 +181,14 @@ CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread) oc_mutex_unlock(thread->threadMutex); CAResult_t res = ca_thread_pool_add_task(thread->threadPool, CAQueueingThreadBaseRoutine, - thread); + thread); if (res != CA_STATUS_OK) { + // update thread status. + oc_mutex_lock(thread->threadMutex); + thread->isStop = true; + oc_mutex_unlock(thread->threadMutex); + OIC_LOG(ERROR, TAG, "thread pool add task error(send thread)."); } @@ -201,7 +206,6 @@ CAResult_t CAQueueingThreadAddData(CAQueueingThread_t *thread, void *data, uint3 if (NULL == data || 0 == size) { OIC_LOG(ERROR, TAG, "data is empty.."); - return CA_STATUS_INVALID_PARAM; } -- 2.7.4