266f3fb91f6af55ae54e6661b2ad579752b1e143
[platform/upstream/iotivity.git] / resource / csdk / connectivity / common / src / uthreadpool.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  ******************************************************************/
19
20 /**
21  * @file    uthreadpool.c
22  * @brief   This file provides APIs related to thread pool
23  */
24
25 #include "uthreadpool.h"
26 #include "logger.h"
27 #include "oic_malloc.h"
28
29 #define TAG PCF("UTHREADPOOL")
30
31 /**
32  * @var gThreadpool
33  * @brief Glib thread pool.
34  */
35 static GThreadPool *gThreadpool = NULL;
36
37 /**
38  * @fn run
39  * @brief function which is registed to glib thread pool.
40  */
41 static void run(void *thread_data, void *user_data);
42
43 CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_pool)
44 {
45     OIC_LOG(DEBUG, TAG, "IN");
46
47     GError *error = NULL;
48
49 #ifdef __ANDROID__
50     //If not intialized, gthreadpool intialize check fails
51     g_thread_init(NULL);
52 #endif //__ANDROID__
53
54     gThreadpool = g_thread_pool_new(run, NULL, num_of_threads, TRUE, &error);
55     if (NULL == gThreadpool)
56     {
57         OIC_LOG(ERROR, TAG, "g_thread_pool_new failed!");
58         if (NULL != error)
59         {
60             OIC_LOG_V(ERROR, TAG, "Error is: %s", error->message);
61             g_error_free(error);
62         }
63         return CA_STATUS_FAILED;
64     }
65
66     *thread_pool = (u_thread_pool_t) gThreadpool;
67
68     OIC_LOG(DEBUG, TAG, "OUT");
69     return CA_STATUS_OK;
70 }
71
72 CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, void (*routine)(void *), 
73                                     void *data)
74 {
75     OIC_LOG(DEBUG, TAG, "IN");
76
77     if (NULL == routine)
78     {
79         OIC_LOG(ERROR, TAG, "routine is NULL!");
80         return CA_STATUS_FAILED;
81     }
82
83     u_thread_msg_t *message = (u_thread_msg_t *) OICMalloc(sizeof(u_thread_msg_t));
84     if (NULL == message)
85     {
86         OIC_LOG(ERROR, TAG, "Memory allocation failed!");
87         return CA_MEMORY_ALLOC_FAILED;
88     }
89
90     message->data = data;
91     message->func = routine;
92
93     g_thread_pool_push((GThreadPool *) thread_pool, (void *) message, NULL);
94
95     OIC_LOG(DEBUG, TAG, "OUT");
96     return CA_STATUS_OK;
97 }
98
99 void u_thread_pool_free(u_thread_pool_t thread_pool)
100 {
101     OIC_LOG(DEBUG, TAG, "IN");
102     if (NULL == thread_pool)
103     {
104         OIC_LOG(DEBUG, TAG, "thread_pool is NULL. Its already freed.");
105         return;
106     }
107
108     GThreadPool *threadpool = (GThreadPool *) thread_pool;
109     g_thread_pool_free(threadpool, TRUE, TRUE);
110
111     OIC_LOG(DEBUG, TAG, "OUT");
112 }
113
114 void run(void *thread_data, void *user_data)
115 {
116     u_thread_msg_t *message = (u_thread_msg_t *) thread_data;
117
118     if (NULL == message)
119     {
120         OIC_LOG(ERROR, TAG, "Invalid task data");
121         return;
122     }
123
124     if(message->func)
125     {
126         OIC_LOG(DEBUG, TAG, "Calling routine with data as parameter");
127         message->func(message->data);
128     }
129
130     // Free message
131     OICFree(message);
132 }