4 * Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include "pims-internal.h"
27 #include "pims-socket.h"
28 #include "pims-ipc-data.h"
29 #include "pims-ipc-data-internal.h"
30 #include "pims-ipc-utils.h"
31 #include "pims-ipc-pubsub.h"
32 #include "pims-ipc-worker.h"
33 #include "pims-ipc-svc.h"
35 #define PIMS_IPC_WORKERS_DEFAULT_MAX_COUNT 3
37 static pims_ipc_svc_s *_g_singleton = NULL;
39 gboolean svc_map_client_worker(gpointer user_data)
41 char *client_id = user_data;
42 pims_ipc_worker_data_s *worker_data;
44 worker_data = worker_get_idle_worker(_g_singleton, client_id);
45 if (NULL == worker_data) {
46 ERR("worker_get_idle_worker() Fail");
47 return G_SOURCE_CONTINUE;
49 return G_SOURCE_REMOVE;
52 API int pims_ipc_svc_init(char *service, gid_t group, mode_t mode)
54 RETVM_IF(_g_singleton, -1, "Already exist");
58 _g_singleton = g_new0(pims_ipc_svc_s, 1);
59 if (NULL == _g_singleton) {
64 ret = cynara_initialize(&_g_singleton->cynara, NULL);
65 if (CYNARA_API_SUCCESS != ret) {
66 char errmsg[1024] = {0};
67 cynara_strerror(ret, errmsg, sizeof(errmsg));
68 ERR("cynara_initialize() Fail(%d,%s)", ret, errmsg);
72 _g_singleton->service = g_strdup(service);
73 _g_singleton->group = group;
74 _g_singleton->mode = mode;
75 _g_singleton->workers_max_count = PIMS_IPC_WORKERS_DEFAULT_MAX_COUNT;
77 /* client id - worker_fd mapping */
78 _g_singleton->client_worker_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
79 ASSERT(_g_singleton->client_worker_map);
81 pthread_mutex_init(&_g_singleton->manager_list_hangup_mutex, 0);
82 _g_singleton->manager_list_hangup = NULL;
87 pthread_mutex_init(&_g_singleton->cynara_mutex, 0);
91 static void __remove_client_fd_map(pims_ipc_svc_s *ipc_svc)
94 pims_ipc_client_map_s *client;
96 cursor = g_list_first(ipc_svc->client_id_fd_map);
99 client = cursor->data;
100 worker_stop_client_worker(ipc_svc, client->id);
105 g_list_free(ipc_svc->client_id_fd_map);
108 API int pims_ipc_svc_deinit(void)
110 RETV_IF(NULL == _g_singleton, -1);
112 g_free(_g_singleton->service);
114 pthread_mutex_destroy(&_g_singleton->manager_list_hangup_mutex);
115 g_list_free_full(_g_singleton->manager_list_hangup, g_free);
117 __remove_client_fd_map(_g_singleton);
119 g_hash_table_destroy(_g_singleton->client_worker_map);
122 pthread_mutex_lock(&_g_singleton->cynara_mutex);
123 int ret = cynara_finish(_g_singleton->cynara);
124 if (CYNARA_API_SUCCESS != ret) {
125 char errmsg[1024] = {0};
126 cynara_strerror(ret, errmsg, sizeof(errmsg));
127 ERR("cynara_finish() Fail(%d,%s)", ret, errmsg);
129 pthread_mutex_unlock(&_g_singleton->cynara_mutex);
130 pthread_mutex_destroy(&_g_singleton->cynara_mutex);
132 g_free(_g_singleton);
138 API int pims_ipc_svc_register(char *module, char *function,
139 pims_ipc_svc_call_cb callback, void *userdata)
141 gchar *call_id = NULL;
142 pims_ipc_svc_cb_s *cb_data = NULL;
144 RETV_IF(NULL == module, -1);
145 RETV_IF(NULL == function, -1);
146 RETV_IF(NULL == callback, -1);
148 cb_data = calloc(1, sizeof(pims_ipc_svc_cb_s));
149 if (NULL == cb_data) {
150 ERR("calloc() Fail");
154 call_id = PIMS_IPC_MAKE_CALL_ID(module, function);
155 VERBOSE("register cb id[%s]", call_id);
157 cb_data->callback = callback;
158 cb_data->user_data = userdata;
160 worker_set_callback(call_id, cb_data);
165 API void pims_ipc_svc_run_main_loop(GMainLoop **main_loop)
167 if (*main_loop == NULL)
168 *main_loop = g_main_loop_new(NULL, FALSE);
173 /* launch worker threads in advance */
174 worker_start_idle_worker(_g_singleton);
175 socket_set_handler(_g_singleton);
178 g_main_loop_run(*main_loop);
180 worker_stop_idle_worker();
182 g_main_loop_unref(*main_loop);
186 API bool pims_ipc_svc_check_privilege(pims_ipc_h ipc, char *privilege)
191 RETV_IF(NULL == privilege, false);
193 pims_ipc_client_info_s *client_info = NULL;
194 client_info = client_get_info(pid);
195 if (NULL == client_info) {
196 ERR("client_info is NULL");
200 pthread_mutex_lock(&_g_singleton->cynara_mutex);
201 ret = cynara_check(_g_singleton->cynara, client_info->smack,
202 client_info->client_session, client_info->uid, privilege);
203 pthread_mutex_unlock(&_g_singleton->cynara_mutex);
205 client_destroy_info(client_info);
207 if (CYNARA_API_ACCESS_ALLOWED == ret)
213 API int pims_ipc_svc_get_smack_label(pims_ipc_h ipc, char **p_smack)
215 pims_ipc_client_info_s *client_info = NULL;
218 client_info = client_get_info(pid);
219 if (NULL == client_info) {
220 ERR("client_info is NULL");
224 if (client_info->smack) {
225 *p_smack = strdup(client_info->smack);
226 if (NULL == *p_smack) {
227 ERR("strdup() return NULL");
228 client_destroy_info(client_info);
233 client_destroy_info(client_info);