iotivity 0.9.0
[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  * @file    uthreadpool.c
21  * @brief   This file provides APIs related to thread pool
22  */
23
24 #include "uthreadpool.h"
25 #include "logger.h"
26 #include "oic_malloc.h"
27 #define TAG PCF("UTHREADPOOL")
28
29 /**
30  * @var gThreadpool
31  * @brief Glib thread pool.
32  */
33 static GThreadPool *gThreadpool;
34
35 /**
36  * @fn run
37  * @brief function which is registed to glib thread pool.
38  */
39 static void run(void *thread_data, void *user_data);
40
41 CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_pool)
42 {
43     OIC_LOG_V(DEBUG, TAG, "IN");
44
45     GError *error = NULL;
46     gThreadpool = g_thread_pool_new(run, NULL, num_of_threads, FALSE, &error);
47     if (NULL == gThreadpool)
48     {
49         OIC_LOG_V(ERROR, TAG, "Error: g_thread_pool_new failed!");
50         if (NULL != error)
51         {
52             OIC_LOG_V(ERROR, TAG, "Error is: %s", error->message);
53             g_error_free(error);
54         }
55         return CA_STATUS_FAILED;
56     }
57     *thread_pool = (u_thread_pool_t) gThreadpool;
58
59     OIC_LOG_V(DEBUG, TAG, "OUT");
60     return CA_STATUS_OK;
61 }
62
63 CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, void (*routine)(void *), void *data)
64 {
65     OIC_LOG_V(DEBUG, TAG, "IN");
66
67     gboolean result = FALSE;
68     if (NULL == routine)
69     {
70         OIC_LOG_V(ERROR, TAG, "Error: routine is NULL!");
71         return CA_STATUS_FAILED;
72     }
73
74     u_thread_msg_t *message = (u_thread_msg_t *) OICMalloc(sizeof(u_thread_msg_t));
75     message->data = data;
76     message->func = routine;
77     result = g_thread_pool_push((GThreadPool *) thread_pool, (void *) message, NULL);
78     if (FALSE == result)
79     {
80         OIC_LOG_V(ERROR, TAG, "Error: Failed to push the task to threadpool!");
81         return CA_STATUS_FAILED;
82     }
83
84     OIC_LOG_V(DEBUG, TAG, "OUT");
85     return CA_STATUS_OK;
86 }
87
88 void u_thread_pool_free(u_thread_pool_t thread_pool)
89 {
90     OIC_LOG_V(DEBUG, TAG, "IN");
91
92     GThreadPool *threadpool = (GThreadPool *) thread_pool;
93     g_thread_pool_free(threadpool, TRUE, TRUE);
94
95     OIC_LOG_V(DEBUG, TAG, "OUT");
96 }
97
98 void run(void *thread_data, void *user_data)
99 {
100     u_thread_msg_t *message = (u_thread_msg_t *) thread_data;
101
102     if (message && message->func)
103     {
104         OIC_LOG_V(DEBUG, TAG, "Calling routine with data as parameter");
105         message->func(message->data);
106     }
107     else
108     {
109         OIC_LOG_V(ERROR, TAG, "Error: Invalid task data");
110         return;
111     }
112
113     //Free message
114     OICFree(message);
115     message = NULL;
116 }