2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.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.
18 #include <string.h> /* strerror */
19 #include <errno.h> /* errno */
20 #include <unistd.h> /* pid_t */
21 #include <stdlib.h> /* free */
30 #include <com-core_packet.h>
31 #include <livebox-errno.h>
34 #include "slave_life.h"
35 #include "slave_rpc.h"
36 #include "client_life.h"
38 #include "fault_manager.h"
43 Ecore_Timer *pong_timer;
46 unsigned long ping_count;
47 unsigned long next_ping_count;
48 Eina_List *pending_list;
52 /* create_command, destroy_command will care these varaibles */
54 struct packet *packet;
55 struct slave_node *slave;
56 int ttl; /* If it fails to handle this, destroy this */
58 /* Don't need to care these data */
59 void (*ret_cb)(struct slave_node *slave, const struct packet *packet, void *cbdata);
64 Eina_List *command_list;
65 Ecore_Timer *command_consuming_timer;
68 .command_consuming_timer = NULL,
71 #define DEFAULT_CMD_TTL 3
73 static inline void prepend_command(struct command *command);
75 static inline struct command *create_command(struct slave_node *slave, const char *pkgname, struct packet *packet)
77 struct command *command;
79 command = calloc(1, sizeof(*command));
81 ErrPrint("Heap: %s\n", strerror(errno));
86 command->pkgname = strdup(pkgname);
87 if (!command->pkgname) {
88 ErrPrint("Heap: %s\n", strerror(errno));
94 command->slave = slave_ref(slave); /*!< To prevent from destroying of the slave while communicating with the slave */
95 command->packet = packet_ref(packet);
96 command->ttl = DEFAULT_CMD_TTL;
101 static inline void destroy_command(struct command *command)
103 slave_unref(command->slave);
104 packet_unref(command->packet);
105 DbgFree(command->pkgname);
109 static inline struct command *pop_command(void)
111 struct command *command;
113 command = eina_list_nth(s_info.command_list, 0);
117 s_info.command_list = eina_list_remove(s_info.command_list, command);
121 static int slave_async_cb(pid_t pid, int handle, const struct packet *packet, void *data)
123 struct command *command = data;
126 ErrPrint("Command is NIL\n");
127 return LB_STATUS_SUCCESS;
132 * command->packet is not valid from here.
134 if (!slave_is_activated(command->slave)) {
135 ErrPrint("Slave is not activated (accidently dead)\n");
137 command->ret_cb(command->slave, packet, command->cbdata);
142 DbgPrint("packet == NULL\n");
144 command->ret_cb(command->slave, packet, command->cbdata);
148 * Slave will be deactivated from dead monitor if it lost its connections.
149 * So we don't need to care it again from here.
151 command->slave = slave_deactivated_by_fault(command->slave);
158 command->ret_cb(command->slave, packet, command->cbdata);
161 destroy_command(command);
162 return LB_STATUS_SUCCESS;
165 static Eina_Bool command_consumer_cb(void *data)
167 struct command *command;
168 struct slave_rpc *rpc;
170 command = pop_command();
172 s_info.command_consuming_timer = NULL;
173 return ECORE_CALLBACK_CANCEL;
176 if (!slave_is_activated(command->slave)) {
177 ErrPrint("Slave is not activated: %s(%d)\n",
178 slave_name(command->slave), slave_pid(command->slave));
182 if (command->pkgname) {
183 struct pkg_info *info;
185 info = package_find(command->pkgname);
186 if (info && package_is_fault(info)) {
187 ErrPrint("info: %p (%s) is fault package\n", info, command->pkgname);
192 rpc = slave_data(command->slave, "rpc");
193 if (!rpc || rpc->handle < 0) {
194 ErrPrint("Slave has no rpc info\n");
198 if (packet_type(command->packet) == PACKET_REQ_NOACK) {
199 if (com_core_packet_send_only(rpc->handle, command->packet) == 0) {
200 /* Keep a slave alive, while processing events */
201 slave_give_more_ttl(command->slave);
202 destroy_command(command);
203 return ECORE_CALLBACK_RENEW;
205 } else if (packet_type(command->packet) == PACKET_REQ) {
206 if (com_core_packet_async_send(rpc->handle, command->packet, 0.0f, slave_async_cb, command) == 0) {
207 /* Keep a slave alive, while processing events */
208 slave_give_more_ttl(command->slave);
209 return ECORE_CALLBACK_RENEW;
215 * What happens at here?
216 * We are failed to send a packet!!!
217 * Let's try to send this again
221 * Do we need to handle this error?
222 * Close current connection and make new one?
223 * how about pended command lists?
225 DbgPrint("Packet type: %d\n", packet_type(command->packet));
226 DbgPrint("Packet: %p\n", command->packet);
227 DbgPrint("Handle: %d\n", rpc->handle);
228 DbgPrint("PID: %d\n", slave_pid(command->slave));
229 DbgPrint("Name: %s\n", slave_name(command->slave));
230 DbgPrint("Package: %s\n", command->pkgname);
232 if (command->ttl == 0) {
233 DbgPrint("Discard packet (%d)\n", command->ttl);
234 destroy_command(command);
236 DbgPrint("Send again (%d)\n", command->ttl);
237 prepend_command(command);
239 return ECORE_CALLBACK_RENEW;
243 command->ret_cb(command->slave, NULL, command->cbdata);
245 destroy_command(command);
246 return ECORE_CALLBACK_RENEW;
249 static inline void prepend_command(struct command *command)
251 s_info.command_list = eina_list_prepend(s_info.command_list, command);
253 if (s_info.command_consuming_timer)
256 s_info.command_consuming_timer = ecore_timer_add(PACKET_TIME, command_consumer_cb, NULL);
257 if (!s_info.command_consuming_timer) {
258 ErrPrint("Failed to add command consumer\n");
259 s_info.command_list = eina_list_remove(s_info.command_list, command);
260 destroy_command(command);
264 static inline void push_command(struct command *command)
266 s_info.command_list = eina_list_append(s_info.command_list, command);
268 if (s_info.command_consuming_timer)
271 s_info.command_consuming_timer = ecore_timer_add(PACKET_TIME, command_consumer_cb, NULL);
272 if (!s_info.command_consuming_timer) {
273 ErrPrint("Failed to add command consumer\n");
274 s_info.command_list = eina_list_remove(s_info.command_list, command);
275 destroy_command(command);
279 static int slave_deactivate_cb(struct slave_node *slave, void *data)
281 struct slave_rpc *rpc;
282 struct command *command;
286 rpc = slave_data(slave, "rpc");
290 * Return negative value will remove this callback from the event list of the slave
292 return LB_STATUS_ERROR_INVALID;
295 if (rpc->pong_timer) {
296 ecore_timer_del(rpc->pong_timer);
297 rpc->pong_timer = NULL;
299 ErrPrint("slave has no pong timer\n");
302 if (rpc->handle < 0) {
303 EINA_LIST_FREE(rpc->pending_list, command) {
304 assert(command->slave == slave);
306 command->ret_cb(command->slave, NULL, command->cbdata);
307 destroy_command(command);
310 EINA_LIST_FOREACH_SAFE(s_info.command_list, l, n, command) {
311 if (command->slave == slave) {
312 s_info.command_list = eina_list_remove(s_info.command_list, command);
314 command->ret_cb(command->slave, NULL, command->cbdata);
315 destroy_command(command);
324 DbgPrint("Reset handle for %d (%d)\n", slave_pid(slave), rpc->handle);
329 * Make statistics table
332 rpc->next_ping_count = 1;
333 return LB_STATUS_SUCCESS;
336 static Eina_Bool ping_timeout_cb(void *data)
338 struct slave_rpc *rpc;
339 struct slave_node *slave = data;
341 rpc = slave_data(slave, "rpc");
343 ErrPrint("Slave RPC is not valid (%s)\n", slave_name(slave));
344 return ECORE_CALLBACK_CANCEL;
349 * Clear the pong_timer
351 rpc->pong_timer = NULL;
353 if (!slave_is_activated(slave)) {
354 ErrPrint("Slave is not activated (%s)\n", slave_name(slave));
355 return ECORE_CALLBACK_CANCEL;
359 * Dead callback will handling this
361 DbgPrint("Slave PING TIMEOUT: %s(%d) : %p\n", slave_name(slave), slave_pid(slave), slave);
362 slave = slave_deactivated_by_fault(slave);
363 DbgPrint("Slave: %p\n", slave);
364 return ECORE_CALLBACK_CANCEL;
367 HAPI int slave_rpc_async_request(struct slave_node *slave, const char *pkgname, struct packet *packet, void (*ret_cb)(struct slave_node *slave, const struct packet *packet, void *data), void *data, int urgent)
369 struct command *command;
370 struct slave_rpc *rpc;
372 command = create_command(slave, pkgname, packet);
374 ErrPrint("Failed to create command\n");
377 ret_cb(slave, NULL, data);
379 packet_unref(packet);
380 return LB_STATUS_ERROR_MEMORY;
383 command->ret_cb = ret_cb;
384 command->cbdata = data;
385 packet_unref(packet);
387 rpc = slave_data(slave, "rpc");
389 ErrPrint("Slave has no RPC\n");
391 ret_cb(slave, NULL, data);
392 destroy_command(command);
393 return LB_STATUS_ERROR_FAULT;
396 if (rpc->handle < 0) {
397 DbgPrint("RPC handle is not ready to use it\n");
398 if (slave_is_secured(slave) && !slave_is_activated(slave)) {
400 DbgPrint("Activate slave forcely\n");
401 ret = slave_activate(slave);
402 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
405 ret_cb(slave, NULL, data);
407 destroy_command(command);
413 rpc->pending_list = eina_list_prepend(rpc->pending_list, command);
415 rpc->pending_list = eina_list_append(rpc->pending_list, command);
417 return LB_STATUS_SUCCESS;
421 prepend_command(command);
423 push_command(command);
425 return LB_STATUS_SUCCESS;
428 HAPI int slave_rpc_request_only(struct slave_node *slave, const char *pkgname, struct packet *packet, int urgent)
430 struct command *command;
431 struct slave_rpc *rpc;
433 command = create_command(slave, pkgname, packet);
435 ErrPrint("Failed to create a command\n");
436 packet_unref(packet);
437 return LB_STATUS_ERROR_MEMORY;
440 command->ret_cb = NULL;
441 command->cbdata = NULL;
442 packet_unref(packet);
444 rpc = slave_data(slave, "rpc");
446 ErrPrint("Slave has no RPC\n");
447 destroy_command(command);
448 return LB_STATUS_ERROR_FAULT;
451 if (rpc->handle < 0) {
452 DbgPrint("RPC handle is not ready to use it\n");
454 if (slave_is_secured(slave) && !slave_is_activated(slave)) {
457 DbgPrint("Activate slave forcely\n");
458 ret = slave_activate(slave);
459 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
460 destroy_command(command);
466 rpc->pending_list = eina_list_prepend(rpc->pending_list, command);
468 rpc->pending_list = eina_list_append(rpc->pending_list, command);
470 return LB_STATUS_SUCCESS;
474 prepend_command(command);
476 push_command(command);
478 return LB_STATUS_SUCCESS;
481 HAPI int slave_rpc_update_handle(struct slave_node *slave, int handle)
483 struct slave_rpc *rpc;
484 struct command *command;
486 rpc = slave_data(slave, "rpc");
488 return LB_STATUS_ERROR_INVALID;
490 DbgPrint("SLAVE: New handle assigned for %d, %d\n", slave_pid(slave), handle);
491 rpc->handle = handle;
493 ecore_timer_del(rpc->pong_timer);
495 rpc->pong_timer = ecore_timer_add(DEFAULT_PING_TIME, ping_timeout_cb, slave);
496 if (!rpc->pong_timer)
497 ErrPrint("Failed to add ping timer\n");
501 * slave_activated will call the activated callback.
502 * activated callback will try to recover the normal instances state.
503 * so the reset_fault should be called after slave_activated function.
505 slave_activated(slave);
507 EINA_LIST_FREE(rpc->pending_list, command) {
508 push_command(command);
511 return LB_STATUS_SUCCESS;
514 HAPI int slave_rpc_init(struct slave_node *slave)
516 struct slave_rpc *rpc;
518 rpc = calloc(1, sizeof(*rpc));
520 ErrPrint("Heap: %s\n", strerror(errno));
521 return LB_STATUS_ERROR_MEMORY;
524 if (slave_set_data(slave, "rpc", rpc) < 0) {
526 return LB_STATUS_ERROR_MEMORY;
529 slave_event_callback_add(slave, SLAVE_EVENT_DEACTIVATE, slave_deactivate_cb, NULL);
532 rpc->next_ping_count = 1;
535 return LB_STATUS_SUCCESS;
538 HAPI int slave_rpc_fini(struct slave_node *slave)
540 struct slave_rpc *rpc;
542 rpc = slave_del_data(slave, "rpc");
544 return LB_STATUS_ERROR_INVALID;
546 slave_event_callback_del(slave, SLAVE_EVENT_DEACTIVATE, slave_deactivate_cb, NULL);
549 ecore_timer_del(rpc->pong_timer);
552 return LB_STATUS_SUCCESS;
555 HAPI int slave_rpc_ping(struct slave_node *slave)
557 struct slave_rpc *rpc;
559 rpc = slave_data(slave, "rpc");
561 ErrPrint("Slave RPC is not valid\n");
562 return LB_STATUS_ERROR_INVALID;
565 if (!slave_is_activated(slave)) {
566 ErrPrint("Slave is not activated\n");
567 return LB_STATUS_ERROR_FAULT;
571 if (rpc->ping_count != rpc->next_ping_count) {
572 ErrPrint("Ping count is not correct\n");
573 rpc->next_ping_count = rpc->ping_count;
575 rpc->next_ping_count++;
577 ecore_timer_reset(rpc->pong_timer);
578 return LB_STATUS_SUCCESS;
581 HAPI int slave_rpc_ping_freeze(struct slave_node *slave)
583 struct slave_rpc *rpc;
585 rpc = slave_data(slave, "rpc");
587 ErrPrint("Slave RPC is not valid\n");
588 return LB_STATUS_ERROR_INVALID;
591 if (!slave_is_activated(slave)) {
592 ErrPrint("Slave is not activated\n");
593 return LB_STATUS_ERROR_FAULT;
596 ecore_timer_freeze(rpc->pong_timer);
597 return LB_STATUS_SUCCESS;
600 HAPI int slave_rpc_ping_thaw(struct slave_node *slave)
602 struct slave_rpc *rpc;
604 rpc = slave_data(slave, "rpc");
606 ErrPrint("Slave RPC is not valid\n");
607 return LB_STATUS_ERROR_INVALID;
610 if (!slave_is_activated(slave)) {
611 ErrPrint("Slave is not activated\n");
612 return LB_STATUS_ERROR_FAULT;
615 ecore_timer_thaw(rpc->pong_timer);
616 return LB_STATUS_SUCCESS;
619 HAPI void slave_rpc_request_update(const char *pkgname, const char *id, const char *cluster, const char *category)
621 struct slave_node *slave;
622 struct pkg_info *info;
623 struct packet *packet;
625 info = package_find(pkgname);
627 ErrPrint("Failed to find a package\n");
631 slave = package_slave(info);
633 ErrPrint("Failed to find a slave for %s\n", pkgname);
637 packet = packet_create_noack("update_content", "ssss", pkgname, id, cluster, category);
639 ErrPrint("Failed to create a new param\n");
643 (void)slave_rpc_request_only(slave, pkgname, packet, 0);
646 HAPI int slave_rpc_handle(struct slave_node *slave)
648 struct slave_rpc *rpc;
650 rpc = slave_data(slave, "rpc");
652 DbgPrint("Slave RPC is not initiated\n");