Changed the type of data added in ca_threadpool_pthreads list.
authorhyuna0213.jo <hyuna0213.jo@samsung.com>
Wed, 14 Dec 2016 08:02:30 +0000 (17:02 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Fri, 16 Dec 2016 09:04:06 +0000 (09:04 +0000)
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>
resource/csdk/connectivity/common/inc/uarraylist.h
resource/csdk/connectivity/common/src/cathreadpool_pthreads.c
resource/csdk/connectivity/common/src/uarraylist.c

index c3eb90b..cf1085b 100644 (file)
@@ -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.
index 624101a..cd2acd3 100644 (file)
@@ -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; 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));
index f7ff470..269efdb 100644 (file)
@@ -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)