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 <hyuna0213.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/15591
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
void *u_arraylist_get(const u_arraylist_t *list, uint32_t index);
/**
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.
* Add data in the array list.
* @param[in] list pointer of array list.
* @param[in] data pointer of data.
void* data;
} 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)
{
// passthrough function to convert the pthreads call to a u_thread_func call
void* ca_thread_pool_pthreads_delegate(void* data)
{
}
CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method,
}
CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method,
{
OIC_LOG(DEBUG, TAG, "IN");
{
OIC_LOG(DEBUG, TAG, "IN");
info->func = method;
info->data = data;
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);
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");
return CA_STATUS_FAILED;
}
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;
}
return CA_STATUS_FAILED;
}
+ oc_mutex_unlock(thread_pool->details->list_lock);
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
{
OIC_LOG(DEBUG, TAG, "IN");
{
OIC_LOG(DEBUG, TAG, "IN");
{
OIC_LOG(ERROR, TAG, "Invalid parameter thread_pool was NULL");
return;
{
OIC_LOG(ERROR, TAG, "Invalid parameter thread_pool was NULL");
return;
oc_mutex_lock(thread_pool->details->list_lock);
oc_mutex_lock(thread_pool->details->list_lock);
- for(uint32_t i = 0; i<u_arraylist_length(thread_pool->details->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));
}
u_arraylist_free(&(thread_pool->details->threads_list));
+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)
bool u_arraylist_add(u_arraylist_t *list, void *data)
{
if (!list)