From 2779c1ae8f64ed6d3a5f80a67193ba166f428c8b Mon Sep 17 00:00:00 2001 From: "hyuna0213.jo" Date: Wed, 14 Dec 2016 17:02:30 +0900 Subject: [PATCH] Changed the type of data added in ca_threadpool_pthreads list. If u_arraylist_add() failed, pthread_join() should be called to release its resources in ca_thread_pool_add_task(). but If the state of target thread is blocked on a condition variable, there is no way to release its resource. (pthread_join() function will wait for the thread to terminate.) So, I changed the type of data added in ca_threadpool_pthreads list to release its resource when ca_thread_pool_free() is called. Change-Id: Ieae5d920368e46230ca312817ed1726bb08e0f2d Signed-off-by: hyuna0213.jo Reviewed-on: https://gerrit.iotivity.org/gerrit/15591 Tested-by: jenkins-iotivity Reviewed-by: Jaehong Jo Reviewed-by: Dan Mihai Reviewed-by: jihwan seo Reviewed-by: Ashok Babu Channa --- resource/csdk/connectivity/common/inc/uarraylist.h | 9 +++ .../common/src/cathreadpool_pthreads.c | 69 +++++++++++++--------- resource/csdk/connectivity/common/src/uarraylist.c | 19 ++++++ 3 files changed, 70 insertions(+), 27 deletions(-) diff --git a/resource/csdk/connectivity/common/inc/uarraylist.h b/resource/csdk/connectivity/common/inc/uarraylist.h index c3eb90b..cf1085b 100644 --- a/resource/csdk/connectivity/common/inc/uarraylist.h +++ b/resource/csdk/connectivity/common/inc/uarraylist.h @@ -89,6 +89,15 @@ void u_arraylist_shrink_to_fit(u_arraylist_t *list); void *u_arraylist_get(const u_arraylist_t *list, uint32_t index); /** + * Returns the index of the data from the array list. + * @param[in] list pointer of array list. + * @param[in] data pointer of data. + * @param[out]index index of array list. + * @return true if success, false otherwise. + */ +bool u_arraylist_get_index(const u_arraylist_t *list, const void *data, uint32_t *index); + +/** * Add data in the array list. * @param[in] list pointer of array list. * @param[in] data pointer of data. diff --git a/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c b/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c index 624101a..cd2acd3 100644 --- a/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c +++ b/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c @@ -61,6 +61,11 @@ typedef struct ca_thread_pool_callback_info_t void* data; } ca_thread_pool_callback_info_t; +typedef struct ca_thread_pool_thread_info_t +{ + oc_thread thread; +} ca_thread_pool_thread_info_t; + // passthrough function to convert the pthreads call to a u_thread_func call void* ca_thread_pool_pthreads_delegate(void* data) { @@ -139,7 +144,7 @@ exit: } CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method, - void *data) + void *data) { OIC_LOG(DEBUG, TAG, "IN"); @@ -159,39 +164,41 @@ 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) + ca_thread_pool_thread_info_t *threadInfo = + (ca_thread_pool_thread_info_t *) OICCalloc(1, sizeof(ca_thread_pool_thread_info_t)); + if (!threadInfo) { - 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; - } + OIC_LOG(ERROR, TAG, "Memory allocation failed"); + OICFree(info); + return CA_STATUS_FAILED; } - oc_thread thread; - int thrRet = oc_thread_new(&thread, ca_thread_pool_pthreads_delegate, info); - if (thrRet != 0) + oc_mutex_lock(thread_pool->details->list_lock); + bool addResult = u_arraylist_add(thread_pool->details->threads_list, (void*) threadInfo); + if (!addResult) { + // Note that this is considered non-fatal. oc_mutex_unlock(thread_pool->details->list_lock); - OIC_LOG_V(ERROR, TAG, "Thread start failed with error %d", thrRet); + OIC_LOG(ERROR, TAG, "Arraylist add failed"); OICFree(info); + OICFree(threadInfo); return CA_STATUS_FAILED; } - bool addResult = u_arraylist_add(thread_pool->details->threads_list, (void*)thread); - oc_mutex_unlock(thread_pool->details->list_lock); - - if(!addResult) + int thrRet = oc_thread_new(&threadInfo->thread, ca_thread_pool_pthreads_delegate, info); + if (thrRet != 0) { - // Note that this is considered non-fatal. - OIC_LOG(ERROR, TAG, "Arraylist add failed"); - oc_thread_free(thread); + uint32_t index = 0; + if (u_arraylist_get_index(thread_pool->details->threads_list, threadInfo, &index)) + { + u_arraylist_remove(thread_pool->details->threads_list, index); + } + 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_unlock(thread_pool->details->list_lock); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -201,7 +208,7 @@ void ca_thread_pool_free(ca_thread_pool_t thread_pool) { OIC_LOG(DEBUG, TAG, "IN"); - if(!thread_pool) + if (!thread_pool) { OIC_LOG(ERROR, TAG, "Invalid parameter thread_pool was NULL"); return; @@ -209,11 +216,19 @@ void ca_thread_pool_free(ca_thread_pool_t thread_pool) oc_mutex_lock(thread_pool->details->list_lock); - for(uint32_t i = 0; idetails->threads_list); ++i) + for (uint32_t i = 0; i < u_arraylist_length(thread_pool->details->threads_list); ++i) { - oc_thread thr = (oc_thread)u_arraylist_get(thread_pool->details->threads_list, i); - oc_thread_wait(thr); - oc_thread_free(thr); + ca_thread_pool_thread_info_t *threadInfo = (ca_thread_pool_thread_info_t *) + u_arraylist_get(thread_pool->details->threads_list, i); + if (threadInfo) + { + if (threadInfo->thread) + { + oc_thread_wait(threadInfo->thread); + oc_thread_free(threadInfo->thread); + } + OICFree(threadInfo); + } } u_arraylist_free(&(thread_pool->details->threads_list)); diff --git a/resource/csdk/connectivity/common/src/uarraylist.c b/resource/csdk/connectivity/common/src/uarraylist.c index f7ff470..269efdb 100644 --- a/resource/csdk/connectivity/common/src/uarraylist.c +++ b/resource/csdk/connectivity/common/src/uarraylist.c @@ -125,6 +125,25 @@ void *u_arraylist_get(const u_arraylist_t *list, uint32_t index) return NULL; } +bool u_arraylist_get_index(const u_arraylist_t *list, const void *data, uint32_t *index) +{ + if (!list || !data) + { + return false; + } + + for (uint32_t i = 0; i < list->length; i++) + { + if (data == list->data[i]) + { + *index = i; + return true; + } + } + + return false; +} + bool u_arraylist_add(u_arraylist_t *list, void *data) { if (!list) -- 2.7.4