2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
26 #include <com-core_packet.h>
31 #include "livebox_internal.h"
32 #include "master_rpc.h"
36 #define DEFAULT_TTL 10
37 #define REQUEST_DELAY 10
41 struct packet *packet;
42 struct livebox *handler;
43 void (*ret_cb)(struct livebox *handler, const struct packet *result, void *data);
55 struct dlist *cmd_list;
61 static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data);
63 static inline struct command *pop_command(void)
66 struct command *command;
68 l = dlist_nth(s_info.cmd_list, 0);
72 command = dlist_data(l);
73 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
77 static inline struct command *create_command(struct livebox *handler, struct packet *packet)
79 struct command *command;
81 command = malloc(sizeof(*command));
83 ErrPrint("Failed to allocate mem for command\n");
87 command->handler = lb_ref(handler);
88 command->packet = packet_ref(packet);
92 static inline void destroy_command(struct command *command)
94 packet_unref(command->packet);
95 lb_unref(command->handler);
99 static gboolean cmd_consumer(gpointer user_data)
101 struct command *command;
103 command = pop_command();
105 s_info.cmd_timer = 0;
111 * Item will be deleted in the "done_cb"
113 * item->param be release by the g_dbus_proxy_call
114 * so to use it again from the done_cb function,
115 * increate the reference counter of the item->param
117 if (command->type == TYPE_NOACK) {
118 if (com_core_packet_send_only(client_fd(), command->packet) < 0)
119 ErrPrint("Failed to send a packet to master\n");
121 destroy_command(command);
123 if (com_core_packet_async_send(client_fd(), command->packet, 0u, done_cb, command) < 0) {
124 DbgPrint("Failed to send a packet to master\n");
126 command->ret_cb(command->handler, NULL, command->data);
127 destroy_command(command);
133 static inline void prepend_command(struct command *command)
135 s_info.cmd_list = dlist_prepend(s_info.cmd_list, command);
136 master_rpc_check_and_fire_consumer();
139 void master_rpc_check_and_fire_consumer(void)
141 if (!s_info.cmd_list || s_info.cmd_timer || client_fd() < 0)
144 s_info.cmd_timer = g_timeout_add(REQUEST_DELAY, cmd_consumer, NULL);
145 if (!s_info.cmd_timer)
146 ErrPrint("Failed to add timer\n");
149 static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data)
151 struct command *command;
158 * Release resource even if
159 * we failed to finish the method call
162 if (command->ttl > 0) {
163 prepend_command(command);
170 if (packet_get(packet, "i", &ret) != 1) {
171 ErrPrint("Invalid result packet\n");
175 DbgPrint("[%s] Returns: %d\n", packet_command(packet), ret);
179 command->ret_cb(command->handler, packet, command->data);
181 destroy_command(command);
185 static inline void push_command(struct command *command)
187 s_info.cmd_list = dlist_append(s_info.cmd_list, command);
188 master_rpc_check_and_fire_consumer();
193 * "handler" could be NULL
195 int master_rpc_async_request(struct livebox *handler, struct packet *packet, int urgent, void (*ret_cb)(struct livebox *handler, const struct packet *result, void *data), void *data)
197 struct command *command;
199 command = create_command(handler, packet);
201 ErrPrint("Failed to create a command\n");
203 ret_cb(handler, NULL, data);
205 packet_unref(packet);
209 command->ret_cb = ret_cb;
210 command->data = data;
211 command->ttl = DEFAULT_TTL;
212 command->type = TYPE_ACK;
215 prepend_command(command);
217 push_command(command);
219 packet_unref(packet);
223 int master_rpc_request_only(struct livebox *handler, struct packet *packet)
225 struct command *command;
227 command = create_command(handler, packet);
229 ErrPrint("Failed to create a command\n");
230 packet_unref(packet);
234 command->ret_cb = NULL;
235 command->data = NULL;
237 command->type = TYPE_NOACK;
239 push_command(command);
240 packet_unref(packet);
244 int master_rpc_clear_fault_package(const char *pkgname)
248 struct command *command;
253 DbgPrint("Clear requests of the fault package(%s)\n", pkgname);
255 dlist_foreach_safe(s_info.cmd_list, l, n, command) {
256 if (!command->handler)
259 if (!strcmp(command->handler->pkgname, pkgname)) {
260 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
262 command->ret_cb(command->handler, NULL, command->data);
264 destroy_command(command);
271 int master_rpc_clear_all_request(void)
273 struct command *command;
277 DbgPrint("Clear all pended requests\n");
279 dlist_foreach_safe(s_info.cmd_list, l, n, command) {
280 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
283 command->ret_cb(command->handler, NULL, command->data);
285 destroy_command(command);
291 int master_rpc_sync_request(struct packet *packet)
293 struct packet *result;
296 result = com_core_packet_oneshot_send(client_addr(), packet, 0.0f);
298 if (packet_get(result, "i", &ret) != 1) {
299 ErrPrint("Invalid result packet\n");
303 packet_unref(result);
305 ErrPrint("Failed to send a sync request\n");
309 packet_unref(packet);