From 48703e12ee82aaf64c0902940616dd7a3909c2bb Mon Sep 17 00:00:00 2001 From: Sung-jae Park Date: Sat, 23 Feb 2013 13:27:29 +0000 Subject: [PATCH] Add change_period service handler Revise the client life-cycle management code service_change_period service handler is added == livebox_service_change_period(pkgname, id, new_period) Change the trigger_update function. Add "id" field. to specify the update target Change-Id: I26b8a3b2c5e6deea3919e1649f0af4f51b93ee38 --- include/client_life.h | 4 +- include/instance.h | 1 + packaging/com.samsung.data-provider-master.spec | 2 +- src/client_life.c | 132 ++++++++++++++---------- src/instance.c | 50 ++++----- src/package.c | 34 +++--- src/server.c | 77 +++++++++++++- src/xmonitor.c | 3 + 8 files changed, 201 insertions(+), 102 deletions(-) diff --git a/include/client_life.h b/include/client_life.h index b577fd3..8a7ceb7 100644 --- a/include/client_life.h +++ b/include/client_life.h @@ -15,8 +15,8 @@ */ enum client_event { + CLIENT_EVENT_ACTIVATE, CLIENT_EVENT_DEACTIVATE, - CLIENT_EVENT_DESTROY, }; enum client_global_event { @@ -32,7 +32,7 @@ struct packet; * Create & Destroy */ extern struct client_node *client_create(pid_t pid, int handle); -extern int client_destroy(struct client_node *client); +#define client_destroy(client) client_unref(client) /*! * \note diff --git a/include/instance.h b/include/instance.h index 69b6d55..30a4aef 100644 --- a/include/instance.h +++ b/include/instance.h @@ -176,6 +176,7 @@ extern const char * const instance_auto_launch(const struct inst_info *inst); extern const int const instance_priority(const struct inst_info *inst); extern const struct client_node * const instance_client(const struct inst_info *inst); extern const double const instance_period(const struct inst_info *inst); +extern const int const instance_timeout(const struct inst_info *inst); extern const int const instance_lb_width(const struct inst_info *inst); extern const int const instance_lb_height(const struct inst_info *inst); extern const int const instance_pd_width(const struct inst_info *inst); diff --git a/packaging/com.samsung.data-provider-master.spec b/packaging/com.samsung.data-provider-master.spec index 1e6fffc..dd8b957 100644 --- a/packaging/com.samsung.data-provider-master.spec +++ b/packaging/com.samsung.data-provider-master.spec @@ -1,6 +1,6 @@ Name: com.samsung.data-provider-master Summary: Master service provider for liveboxes. -Version: 0.16.13 +Version: 0.16.14 Release: 1 Group: framework/livebox License: Flora License diff --git a/src/client_life.c b/src/client_life.c index 585d45c..f795feb 100644 --- a/src/client_life.c +++ b/src/client_life.c @@ -74,14 +74,14 @@ struct client_node { int paused; Eina_List *event_deactivate_list; - Eina_List *event_destroy_list; + Eina_List *event_activate_list; Eina_List *data_list; Eina_List *subscribe_list; int faulted; }; -static inline void invoke_global_destroy_cb(struct client_node *client) +static inline void invoke_global_destroyed_cb(struct client_node *client) { Eina_List *l; Eina_List *n; @@ -102,7 +102,7 @@ static inline void invoke_global_destroy_cb(struct client_node *client) } } -static inline void invoke_global_create_cb(struct client_node *client) +static inline void invoke_global_created_cb(struct client_node *client) { Eina_List *l; Eina_List *n; @@ -123,32 +123,55 @@ static inline void invoke_global_create_cb(struct client_node *client) } } -static inline void destroy_client_data(struct client_node *client) +static inline void invoke_deactivated_cb(struct client_node *client) { - struct event_item *event; - struct data_item *data; - struct subscribe_item *item; + struct event_item *item; Eina_List *l; Eina_List *n; + int ret; - DbgPrint("Client %p is destroyed\n", client); - - invoke_global_destroy_cb(client); - client_rpc_fini(client); /*!< Finalize the RPC after invoke destroy callbacks */ - - EINA_LIST_FOREACH_SAFE(client->event_destroy_list, l, n, event) { - if (!event->cb) { - DbgPrint("Callback function is not valid\n"); - continue; + client_ref(client); /*!< Prevent from client deletion in the callbacks */ + EINA_LIST_FOREACH_SAFE(client->event_deactivate_list, l, n, item) { + ret = item->cb(client, item->data); + if (ret < 0) { + if (eina_list_data_find(client->event_deactivate_list, item)) { + client->event_deactivate_list = eina_list_remove(client->event_deactivate_list, item); + DbgFree(item); + } } + } + client_unref(client); +} - (void)event->cb(client, event->data); +static inline void invoke_activated_cb(struct client_node *client) +{ + struct event_item *item; + Eina_List *l; + Eina_List *n; + int ret; - if (eina_list_data_find(client->event_destroy_list, event)) { - client->event_destroy_list = eina_list_remove(client->event_destroy_list, event); - DbgFree(event); + client_ref(client); /*!< Prevent from client deletion in the callbacks */ + EINA_LIST_FOREACH_SAFE(client->event_activate_list, l, n, item) { + ret = item->cb(client, item->data); + if (ret < 0) { + if (eina_list_data_find(client->event_activate_list, item)) { + client->event_activate_list = eina_list_remove(client->event_activate_list, item); + DbgFree(item); + } } } +} + +static inline void destroy_client_data(struct client_node *client) +{ + struct event_item *event; + struct data_item *data; + struct subscribe_item *item; + + DbgPrint("Client %p is destroyed\n", client); + + invoke_global_destroyed_cb(client); + client_rpc_fini(client); /*!< Finalize the RPC after invoke destroy callbacks */ EINA_LIST_FREE(client->data_list, data) { DbgPrint("Tag is not cleared (%s)\n", data->tag); @@ -194,15 +217,36 @@ static inline struct client_node *create_client_data(pid_t pid) client->refcnt = 1; s_info.client_list = eina_list_append(s_info.client_list, client); + + /*! + * \note + * Right after create a client ADT, + * We assume that the client is paused. + */ + client_paused(client); + xmonitor_handle_state_changes(); return client; } static Eina_Bool created_cb(void *data) { - invoke_global_create_cb(data); + invoke_global_created_cb(data); + invoke_activated_cb(data); + /*! + * \note + * Client PAUSE/RESUME event must has to be sent after created event. + */ + xmonitor_update_state(client_pid(data)); return ECORE_CALLBACK_CANCEL; } +/*! + * \note + * Noramlly, client ADT is created when it send the "acquire" packet. + * It means we have the handle for communicating with the client already, + * So we just create its ADT in this function. + * And invoke the global created event & activated event callbacks + */ HAPI struct client_node *client_create(pid_t pid, int handle) { struct client_node *client; @@ -225,24 +269,20 @@ HAPI struct client_node *client_create(pid_t pid, int handle) client = client_unref(client); ErrPrint("Failed to initialize the RPC for %d, Destroy client data %p(has to be 0x0)\n", pid, client); } else { + /*! + * \note + * To save the time to send reply packet to the client. + */ if (ecore_timer_add(DELAY_TIME, created_cb, client) == NULL) { ErrPrint("Failed to add a timer for client created event\n"); client = client_unref(client); return NULL; } - - xmonitor_update_state(pid); } return client; } -HAPI int client_destroy(struct client_node *client) -{ - client_unref(client); - return 0; -} - HAPI struct client_node *client_ref(struct client_node *client) { if (!client) @@ -328,26 +368,6 @@ HAPI int client_count(void) return eina_list_count(s_info.client_list); } -static inline void invoke_deactivated_cb(struct client_node *client) -{ - struct event_item *item; - Eina_List *l; - Eina_List *n; - int ret; - - client_ref(client); /*!< Prevent deleting from callback */ - EINA_LIST_FOREACH_SAFE(client->event_deactivate_list, l, n, item) { - ret = item->cb(client, item->data); - if (ret < 0) { - if (eina_list_data_find(client->event_deactivate_list, item)) { - client->event_deactivate_list = eina_list_remove(client->event_deactivate_list, item); - DbgFree(item); - } - } - } - client_unref(client); -} - HAPI int client_deactivated_by_fault(struct client_node *client) { if (!client || client->faulted) @@ -358,7 +378,7 @@ HAPI int client_deactivated_by_fault(struct client_node *client) client->pid = (pid_t)-1; invoke_deactivated_cb(client); - client_destroy(client); + (void)client_destroy(client); /*! * \todo * Who invokes this function has to care the reference counter of a client @@ -424,8 +444,8 @@ HAPI int client_event_callback_add(struct client_node *client, enum client_event case CLIENT_EVENT_DEACTIVATE: client->event_deactivate_list = eina_list_prepend(client->event_deactivate_list, item); break; - case CLIENT_EVENT_DESTROY: - client->event_destroy_list = eina_list_prepend(client->event_destroy_list, item); + case CLIENT_EVENT_ACTIVATE: + client->event_activate_list = eina_list_prepend(client->event_activate_list, item); break; default: DbgFree(item); @@ -457,10 +477,10 @@ HAPI int client_event_callback_del(struct client_node *client, enum client_event } break; - case CLIENT_EVENT_DESTROY: - EINA_LIST_FOREACH_SAFE(client->event_destroy_list, l, n, item) { + case CLIENT_EVENT_ACTIVATE: + EINA_LIST_FOREACH_SAFE(client->event_activate_list, l, n, item) { if (item->cb == cb && item->data == data) { - client->event_destroy_list = eina_list_remove(client->event_destroy_list, item); + client->event_activate_list = eina_list_remove(client->event_activate_list, item); DbgFree(item); return 0; } @@ -562,7 +582,7 @@ HAPI int client_fini(void) Eina_List *n; EINA_LIST_FOREACH_SAFE(s_info.client_list, l, n, client) { - client_destroy(client); + (void)client_destroy(client); } EINA_LIST_FREE(s_info.create_event_list, handler) { diff --git a/src/instance.c b/src/instance.c index feb3abc..06149c6 100644 --- a/src/instance.c +++ b/src/instance.c @@ -102,6 +102,8 @@ struct inst_info { } canvas; const char *auto_launch; + int timeout; + double period; } lb; struct { @@ -122,9 +124,6 @@ struct inst_info { int pended_update_cnt; } pd; - int timeout; - double period; - struct client_node *client; /*!< Owner - creator */ Eina_List *client_list; /*!< Viewer list */ int refcnt; @@ -309,7 +308,7 @@ HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_no !!inst->client, package_pinup(inst->info), lb_type, pd_type, - inst->period, inst->title, + inst->lb.period, inst->title, inst->is_pinned_up); if (!packet) { ErrPrint("Failed to build a packet for %s\n", package_name(inst->info)); @@ -371,7 +370,7 @@ static int instance_broadcast_created_event(struct inst_info *inst) !!inst->client, package_pinup(inst->info), lb_type, pd_type, - inst->period, inst->title, + inst->lb.period, inst->title, inst->is_pinned_up); if (!packet) { ErrPrint("Failed to build a packet for %s\n", package_name(inst->info)); @@ -537,14 +536,14 @@ static inline int fork_package(struct inst_info *inst, const char *pkgname) instance_set_pd_info(inst, package_pd_width(info), package_pd_height(info)); - inst->timeout = package_timeout(info); - inst->period = package_period(info); + inst->lb.timeout = package_timeout(info); + inst->lb.period = package_period(info); inst->info = info; if (package_secured(info)) { DbgPrint("Register the update timer for secured livebox [%s]\n", package_name(info)); - inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst); + inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst); if (!inst->update_timer) ErrPrint("Failed to add an update timer for instance %s\n", inst->id); else @@ -986,7 +985,7 @@ static void activate_cb(struct slave_node *slave, const struct packet *packet, v struct inst_info *new_inst; new_inst = instance_create(inst->client, util_timestamp(), package_name(inst->info), inst->content, inst->cluster, inst->category, - inst->period, 0, 0); + inst->lb.period, 0, 0); if (!new_inst) ErrPrint("Failed to create a new instance\n"); } else { @@ -1266,9 +1265,9 @@ HAPI int instance_reactivate(struct inst_info *inst) package_name(inst->info), inst->id, inst->content, - inst->timeout, + inst->lb.timeout, !!package_lb_path(inst->info), - inst->period, + inst->lb.period, inst->cluster, inst->category, inst->lb.width, inst->lb.height, @@ -1330,9 +1329,9 @@ HAPI int instance_activate(struct inst_info *inst) package_name(inst->info), inst->id, inst->content, - inst->timeout, + inst->lb.timeout, !!package_lb_path(inst->info), - inst->period, + inst->lb.period, inst->cluster, inst->category, !!inst->client, @@ -1790,12 +1789,12 @@ static void set_period_cb(struct slave_node *slave, const struct packet *packet, } if (ret == 0) - cbdata->inst->period = cbdata->period; + cbdata->inst->lb.period = cbdata->period; else ErrPrint("Failed to set period %d\n", ret); out: - result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->period, package_name(cbdata->inst->info), cbdata->inst->id); + result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->lb.period, package_name(cbdata->inst->info), cbdata->inst->id); if (result) (void)CLIENT_SEND_EVENT(cbdata->inst, result); else @@ -1817,25 +1816,25 @@ static Eina_Bool timer_updator_cb(void *data) inst = cbdata->inst; DbgFree(cbdata); - DbgPrint("Update period is changed to %lf from %lf\n", period, inst->period); + DbgPrint("Update period is changed to %lf from %lf\n", period, inst->lb.period); - inst->period = period; + inst->lb.period = period; if (inst->update_timer) { - if (inst->period == 0.0f) { + if (inst->lb.period == 0.0f) { ecore_timer_del(inst->update_timer); inst->update_timer = NULL; } else { - util_timer_interval_set(inst->update_timer, inst->period); + util_timer_interval_set(inst->update_timer, inst->lb.period); } - } else if (inst->period > 0.0f) { - inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst); + } else if (inst->lb.period > 0.0f) { + inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst); if (!inst->update_timer) ErrPrint("Failed to add an update timer for instance %s\n", inst->id); else timer_freeze(inst); /* Freeze the update timer as default */ } - result = packet_create_noack("period_changed", "idss", 0, inst->period, package_name(inst->info), inst->id); + result = packet_create_noack("period_changed", "idss", 0, inst->lb.period, package_name(inst->info), inst->id); if (result) (void)CLIENT_SEND_EVENT(inst, result); else @@ -2092,9 +2091,14 @@ HAPI const struct client_node *const instance_client(const struct inst_info *ins return inst->client; } +HAPI const int const instance_timeout(const struct inst_info *inst) +{ + return inst->lb.timeout; +} + HAPI const double const instance_period(const struct inst_info *inst) { - return inst->period; + return inst->lb.period; } HAPI const int const instance_lb_width(const struct inst_info *inst) diff --git a/src/package.c b/src/package.c index a345c68..5b76c64 100644 --- a/src/package.c +++ b/src/package.c @@ -82,6 +82,9 @@ struct pkg_info { unsigned int size_list; char *auto_launch; int pinup; + int timeout; + double period; + char *libexec; } lb; struct { @@ -107,12 +110,9 @@ struct pkg_info { } pd; int network; - int timeout; - double period; int secured; char *script; /* script type: edje, ... */ char *abi; - char *libexec; int fault_count; struct fault_info *fault_info; @@ -288,7 +288,7 @@ static inline void destroy_package(struct pkg_info *info) DbgFree(info->script); DbgFree(info->abi); DbgFree(info->pkgname); - DbgFree(info->libexec); + DbgFree(info->lb.libexec); DbgFree(info->lb.auto_launch); DbgFree(info); @@ -428,14 +428,14 @@ static inline int load_conf(struct pkg_info *info) return -ENOMEM; } - info->timeout = parser_timeout(parser); + info->lb.timeout = parser_timeout(parser); info->network = parser_network(parser); - info->period = parser_period(parser); - if (info->period < 0.0f) - info->period = 0.0f; - else if (info->period > 0.0f && info->period < MINIMUM_PERIOD) - info->period = MINIMUM_PERIOD; + info->lb.period = parser_period(parser); + if (info->lb.period < 0.0f) + info->lb.period = 0.0f; + else if (info->lb.period > 0.0f && info->lb.period < MINIMUM_PERIOD) + info->lb.period = MINIMUM_PERIOD; info->lb.size_list = parser_size(parser); @@ -707,22 +707,22 @@ HAPI struct slave_node * const package_slave(const struct pkg_info *info) HAPI const int const package_timeout(const struct pkg_info *info) { - return info->timeout; + return info->lb.timeout; } HAPI void package_set_timeout(struct pkg_info *info, int timeout) { - info->timeout = timeout; + info->lb.timeout = timeout; } HAPI const double const package_period(const struct pkg_info *info) { - return info->period; + return info->lb.period; } HAPI void package_set_period(struct pkg_info *info, double period) { - info->period = period; + info->lb.period = period; } HAPI const int const package_secured(const struct pkg_info *info) @@ -974,7 +974,7 @@ HAPI void package_set_lb_type(struct pkg_info *info, enum lb_type type) HAPI const char * const package_libexec(struct pkg_info *info) { - return info->libexec; + return info->lb.libexec; } HAPI int package_set_libexec(struct pkg_info *info, const char *libexec) @@ -987,8 +987,8 @@ HAPI int package_set_libexec(struct pkg_info *info, const char *libexec) return -ENOMEM; } - DbgFree(info->libexec); - info->libexec = tmp; + DbgFree(info->lb.libexec); + info->lb.libexec = tmp; return 0; } diff --git a/src/server.c b/src/server.c index b48b580..b0351d4 100644 --- a/src/server.c +++ b/src/server.c @@ -4704,17 +4704,73 @@ out: return result; } +static struct packet *service_change_period(pid_t pid, int handle, const struct packet *packet) +{ + struct inst_info *inst; + struct packet *result; + const char *pkgname; + const char *id; + double period; + int ret; + + ret = packet_get(packet, "ssd", &pkgname, &id, &period); + if (ret != 3) { + ErrPrint("Invalid packet\n"); + ret = -EINVAL; + goto out; + } + + if (!strlen(id)) { + struct pkg_info *pkg; + + pkg = package_find(pkgname); + if (!pkg) { + ret = -ENOENT; + } else if (package_is_fault(pkg)) { + ret = -EFAULT; + } else { + Eina_List *inst_list; + Eina_List *l; + + inst_list = package_instance_list(pkg); + EINA_LIST_FOREACH(inst_list, l, inst) { + ret = instance_set_period(inst, period); + if (ret < 0) + DbgPrint("Failed to change the period of %s to (%lf)\n", instance_id(inst), period); + } + } + } else { + inst = package_find_instance_by_id(pkgname, id); + if (!inst) + ret = -ENOENT; + else if (package_is_fault(instance_package(inst))) + ret = -EFAULT; + else + ret = instance_set_period(inst, period); + } + + DbgPrint("Change the update period: %s(%s), %lf : %d\n", pkgname, id, period, ret); +out: + result = packet_create_reply(packet, "i", ret); + if (!result) + ErrPrint("Failed to create a packet\n"); + + return result; +} + static struct packet *service_update(pid_t pid, int handle, const struct packet *packet) { + struct pkg_info *pkg; struct packet *result; const char *pkgname; + const char *id; const char *cluster; const char *category; char *lb_pkgname; int ret; - ret = packet_get(packet, "sss", &pkgname, &cluster, &category); - if (ret != 3) { + ret = packet_get(packet, "ssss", &pkgname, &id, &cluster, &category); + if (ret != 4) { ErrPrint("Invalid Packet\n"); ret = -EINVAL; goto out; @@ -4727,11 +4783,22 @@ static struct packet *service_update(pid_t pid, int handle, const struct packet goto out; } + pkg = package_find(lb_pkgname); + if (!pkg) { + ret = -ENOENT; + goto out; + } + + if (package_is_fault(pkg)) { + ret = -EFAULT; + goto out; + } + /*! * \TODO * Validate the update requstor. */ - slave_rpc_request_update(lb_pkgname, "", cluster, category); + slave_rpc_request_update(lb_pkgname, id, cluster, category); DbgFree(lb_pkgname); ret = 0; @@ -5310,6 +5377,10 @@ static struct method s_service_table[] = { .handler = service_update, }, { + .cmd = "service_change_period", + .handler = service_change_period, + }, + { .cmd = NULL, .handler = NULL, }, diff --git a/src/xmonitor.c b/src/xmonitor.c index ef89efd..2260133 100644 --- a/src/xmonitor.c +++ b/src/xmonitor.c @@ -161,6 +161,9 @@ HAPI int xmonitor_update_state(int target_pid) struct client_node *client; int pid; + if (!USE_XMONITOR) + return 0; + win = ecore_x_window_focus_get(); pid = get_pid(win); -- 2.7.4