Sync with the latest 2.4 tizen. 36/43536/1
authorSung-jae Park <nicesj.park@samsung.com>
Fri, 10 Jul 2015 04:22:19 +0000 (13:22 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Fri, 10 Jul 2015 04:22:19 +0000 (13:22 +0900)
Change-Id: Ie3bffa9784d0197c08b79ababf6f4b87a31a8330

16 files changed:
CMakeLists.txt
include/package.h
include/slave_life.h
packaging/data-provider-master.spec
pkgmgr_widget/common/src/common.c
src/buffer_handler.c
src/event.c
src/file_service.c
src/instance.c
src/package.c
src/server.c
src/service_common.c
src/slave_life.c
src/slave_rpc.c
src/util.c
widget-mgr/src/widget-mgr.c

index 3c46a54..fd4acd9 100644 (file)
@@ -60,6 +60,9 @@ ADD_DEFINITIONS("-DPATH_MAX=256")
 ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"")
 ADD_DEFINITIONS("-DLOCALEDIR=\"${LOCALEDIR}\"")
 
+ADD_DEFINITIONS("-D_GNU_SOURCE")
+ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64")
+
 ADD_DEFINITIONS("-DINFO_SOCKET=\"/opt/usr/share/live_magazine/.live.socket\"")
 ADD_DEFINITIONS("-DCLIENT_SOCKET=\"/opt/usr/share/live_magazine/.client.socket\"")
 ADD_DEFINITIONS("-DSLAVE_SOCKET=\"/opt/usr/share/live_magazine/.slave.socket\"")
index 8da7d94..9159803 100644 (file)
@@ -120,6 +120,5 @@ extern int package_is_enabled(const char *appid);
 extern int package_faulted(struct pkg_info *info, int broadcast);
 extern char *package_get_pkgid(const char *appid);
 
-extern int package_del_instance_by_category(const char *category, const char *except_widget_id);
 extern int package_instance_count(struct pkg_info *info);
 /* End of a file */
index 0529ad4..db52ebd 100644 (file)
@@ -221,4 +221,10 @@ extern void slave_set_valid(struct slave_node *slave);
 extern void slave_set_extra_bundle_data(struct slave_node *slave, const char *extra_bundle_data);
 extern const char *slave_extra_bundle_data(struct slave_node *slave);
 
+extern int slave_is_watch(struct slave_node *slave);
+extern void slave_set_is_watch(struct slave_node *slave, int flag);
+
+extern int slave_set_resource_limit(struct slave_node *slave, unsigned int soft, unsigned int hard);
+extern int slave_get_resource_limit(struct slave_node *slave, unsigned int *soft, unsigned int *hard);
+
 /* End of a file */
index 2e83e21..fe6db42 100644 (file)
@@ -2,10 +2,10 @@
 
 Name: data-provider-master
 Summary: Master service provider for widgetes
-Version: 1.1.7
+Version: 1.1.8
 Release: 1
 Group: Applications/Core Applications
-License: Flora License, Version 1.1
+License: Flora-1.1
 Source0: %{name}-%{version}.tar.gz
 Source1001: %{name}.manifest
 BuildRequires: cmake, gettext-tools, smack, coreutils
index 6e600d9..62b10a0 100644 (file)
@@ -2194,6 +2194,36 @@ static int update_category(struct widget *widget, xmlNodePtr node)
        return 0;
 }
 
+static inline xmlChar *pkgmgr_get_mainapp(char *pkgid)
+{
+       pkgmgrinfo_pkginfo_h handle;
+       xmlChar *ret;
+       char *tmp;
+
+       if (pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle) != PMINFO_R_OK) {
+               ErrPrint("Unable to get mainapp: %s\n", pkgid);
+               return NULL;
+       }
+
+       tmp = NULL;
+       ret = NULL;
+       if (pkgmgrinfo_pkginfo_get_mainappid(handle, &tmp) == PMINFO_R_OK) {
+               if (tmp) {
+                       ret = xmlStrdup((xmlChar *)tmp);
+                       if (!ret) {
+                               ErrPrint("xmlStrdup: %d\n", errno);
+                       }
+               } else {
+                       ErrPrint("mainappid is NULL (%s)\n", pkgid);
+               }
+       } else {
+               ErrPrint("Failed to get mainappid (%s)\n", pkgid);
+       }
+
+       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+       return ret;
+}
+
 static void update_ui_appid(struct widget *widget, xmlNodePtr node)
 {
        xmlChar *uiapp;
@@ -3042,12 +3072,22 @@ int db_install_widget(xmlNodePtr node, const char *appid)
                xmlFree(tmp);
        }
 
+       /**
+        * @note
+        * "primary" == "main"
+        */
        if (xmlHasProp(node, (const xmlChar *)"primary")) {
                tmp = xmlGetProp(node, (const xmlChar *)"primary");
                widget->primary = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
                xmlFree(tmp);
        }
 
+       if (xmlHasProp(node, (const xmlChar *)"main")) {
+               tmp = xmlGetProp(node, (const xmlChar *)"main");
+               widget->primary = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
+               xmlFree(tmp);
+       }
+
        if (xmlHasProp(node, (const xmlChar *)"script")) {
                widget->script = xmlGetProp(node, (const xmlChar *)"script");
                if (!widget->script) {
@@ -3067,6 +3107,10 @@ int db_install_widget(xmlNodePtr node, const char *appid)
                xmlFree(tmp);
        }
 
+       /**
+        * @note
+        * "period" == "update-period"
+        */
        if (xmlHasProp(node, (const xmlChar *)"period")) {
                widget->period = xmlGetProp(node, (const xmlChar *)"period");
                if (!widget->period) {
@@ -3074,6 +3118,13 @@ int db_install_widget(xmlNodePtr node, const char *appid)
                }
        }
 
+       if (xmlHasProp(node, (const xmlChar *)"update-period")) {
+               widget->period = xmlGetProp(node, (const xmlChar *)"update-period");
+               if (!widget->period) {
+                       ErrPrint("Period is NIL\n");
+               }
+       }
+
        if (xmlHasProp(node, (const xmlChar *)"timeout")) {
                widget->timeout = xmlGetProp(node, (const xmlChar *)"timeout");
                if (!widget->timeout) {
@@ -3122,7 +3173,7 @@ int db_install_widget(xmlNodePtr node, const char *appid)
         * And there is no "box" tag.
         */
        if (!xmlHasProp(node, (const xmlChar *)"type")) {
-               widget->widget_type = WIDGET_TYPE_FILE;
+               widget->widget_type = WIDGET_TYPE_BUFFER;
        } else {
                xmlChar *type;
 
@@ -3140,7 +3191,7 @@ int db_install_widget(xmlNodePtr node, const char *appid)
                        } else if (!xmlStrcasecmp(type, (const xmlChar *)"elm")) {
                                widget->widget_type = WIDGET_TYPE_UIFW;
                        } else { /* Default */
-                               widget->widget_type = WIDGET_TYPE_FILE;
+                               widget->widget_type = WIDGET_TYPE_BUFFER;
                        }
 
                        xmlFree(type);
@@ -3300,6 +3351,16 @@ int db_install_widget(xmlNodePtr node, const char *appid)
                }
        }
 
+       if (widget->uiapp) {
+               /**
+                * @note
+                * If there is no speicifed UI-App related with this widget,
+                * Set default to Main UI App.
+                */
+               widget->uiapp = pkgmgr_get_mainapp((char *)appid);
+               DbgPrint("Default MAIN UI-APP: [%s]\n", (char *)widget->uiapp);
+       }
+
        return db_insert_widget(widget, appid);
 }
 
index 2d569d3..c8a9a8e 100644 (file)
  * limitations under the License.
  */
 
+#if defined(_FILE_OFFSET_BITS)
+#undef _FILE_OFFSET_BITS
+#endif
+
 #include <stdio.h>
 #include <unistd.h> /* access */
 #include <sys/mman.h>
@@ -1345,7 +1349,7 @@ static inline widget_fb_t raw_open_file(const char *filename)
        buffer->state = WIDGET_FB_STATE_CREATED;
        buffer->type = WIDGET_FB_TYPE_FILE;
        buffer->refcnt = 0;
-       buffer->info = (void *)off;
+       buffer->info = ((void *)off);
 
        ret = read(fd, buffer->data, off);
        if (ret < 0) {
index 47ce633..4930cea 100644 (file)
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#define _GNU_SOURCE
 #include <stdio.h>
 #include <errno.h>
 #include <pthread.h>
index e39c1de..e76adc3 100644 (file)
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#define _GNU_SOURCE
 #include <stdio.h>
 #include <pthread.h>
 #include <sys/time.h>
@@ -378,7 +377,8 @@ static int send_file(int handle, const struct request_item *item)
                body = malloc(sizeof(*body));
                if (!body) {
                        ErrPrint("malloc: %d\n", errno);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto errout;
                }
 
                body->size = -1;
index 2bfbd92..9fcc87b 100644 (file)
@@ -163,6 +163,7 @@ struct inst_info {
        int refcnt;
 
        Ecore_Timer *update_timer; /*!< Only used for secured widget */
+       int update_timer_freezed; /*!< Tizen 2.3 doesn't support ecore_timer_freeze_get API. it is introduced in Tizen 2.4. For the compatibility, master uses this */
 
        enum event_process {
                INST_EVENT_PROCESS_IDLE = 0x00,
@@ -207,7 +208,13 @@ static inline void timer_thaw(struct inst_info *inst)
        double delay;
        double sleep_time;
 
+       if (!inst->update_timer_freezed) {
+               return;
+       }
+
        ecore_timer_thaw(inst->update_timer);
+       inst->update_timer_freezed = 0;
+
        period = ecore_timer_interval_get(inst->update_timer);
        pending = ecore_timer_pending_get(inst->update_timer);
        delay = util_time_delay_for_compensation(period) - pending;
@@ -227,7 +234,12 @@ static inline void timer_thaw(struct inst_info *inst)
 
 static inline void timer_freeze(struct inst_info *inst)
 {
+       if (inst->update_timer_freezed) {
+               return;
+       }
+
        ecore_timer_freeze(inst->update_timer);
+       inst->update_timer_freezed = 1;
 
        if (ecore_timer_interval_get(inst->update_timer) <= 1.0f) {
                return;
@@ -323,8 +335,8 @@ static inline int instance_recover_visible_state(struct inst_info *inst)
                break;
        case WIDGET_HIDE_WITH_PAUSE:
                ret = pause_widget(inst);
+               (void)instance_freeze_updator(inst);
 
-               instance_freeze_updator(inst);
                break;
        default:
                ret = WIDGET_ERROR_INVALID_PARAMETER;
@@ -918,11 +930,7 @@ static inline int fork_package(struct inst_info *inst, const char *pkgname)
        if (package_secured(info) || (WIDGET_IS_INHOUSE(package_abi(info)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL)) {
                if (inst->widget.period > 0.0f) {
                        inst->update_timer = util_timer_add(inst->widget.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 */
-                       }
+                       (void)instance_freeze_updator(inst);
                } else {
                        inst->update_timer = NULL;
                }
@@ -1171,9 +1179,6 @@ HAPI struct inst_info *instance_unref(struct inst_info *inst)
 static void deactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
 {
        struct inst_info *inst = data;
-       const char *category;
-       int set_to_terminate;
-       struct pkg_info *pkg;
        int ret;
 
        /*!
@@ -1223,11 +1228,7 @@ static void deactivate_cb(struct slave_node *slave, const struct packet *packet,
                        instance_reactivate(inst);
                        break;
                case INST_DESTROYED:
-                       pkg = instance_package(inst);
-                       category = package_category(pkg);
-                       set_to_terminate = (category && !strcmp(category, CATEGORY_WATCH_CLOCK));
-
-                       if (set_to_terminate) {
+                       if (slave_is_watch(slave)) {
                                /**
                                 * @note
                                 * In case of the watch app.
@@ -1241,7 +1242,7 @@ static void deactivate_cb(struct slave_node *slave, const struct packet *packet,
                                 * The master will not change the states of the slave as a faulted one.
                                 */
                                DbgPrint("Change the slave state for Watch app\n");
-                               slave_set_state(package_slave(pkg), SLAVE_REQUEST_TO_TERMINATE);
+                               slave_set_state(slave, SLAVE_REQUEST_TO_TERMINATE);
                        }
 
                        if (inst->unicast_delete_event) {
@@ -2581,6 +2582,10 @@ HAPI int instance_set_pinup(struct inst_info *inst, int pinup)
 
 HAPI int instance_freeze_updator(struct inst_info *inst)
 {
+       if (WIDGET_CONF_UPDATE_ON_PAUSE) {
+               return WIDGET_ERROR_DISABLED;
+       }
+
        if (!inst->update_timer) {
                return WIDGET_ERROR_INVALID_PARAMETER;
        }
@@ -2638,7 +2643,7 @@ HAPI int instance_set_visible_state(struct inst_info *inst, enum widget_visible_
                        inst->visible = WIDGET_HIDE_WITH_PAUSE;
                }
 
-               instance_freeze_updator(inst);
+               (void)instance_freeze_updator(inst);
                monitor_multicast_state_change_event(package_name(inst->info), MONITOR_EVENT_PAUSED, instance_id(inst), instance_content(inst));
                break;
 
@@ -2667,7 +2672,7 @@ HAPI int instance_watch_recover_visible_state(struct inst_info *inst)
                break;
        case WIDGET_HIDE_WITH_PAUSE:
                (void)pause_widget(inst);
-               instance_freeze_updator(inst);
+               (void)instance_freeze_updator(inst);
                break;
        default:
                return WIDGET_ERROR_INVALID_PARAMETER;
@@ -2843,11 +2848,7 @@ static Eina_Bool timer_updator_cb(void *data)
                }
        } else if (inst->widget.period > 0.0f) {
                inst->update_timer = util_timer_add(inst->widget.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 */
-               }
+               (void)instance_freeze_updator(inst);
        }
 
        result = packet_create_noack((const char *)&cmd, "idss", 0, inst->widget.period, package_name(inst->info), inst->id);
index 13d66d1..8b534a1 100644 (file)
@@ -149,35 +149,34 @@ static int slave_activated_cb(struct slave_node *slave, void *data)
        Eina_List *n;
        int cnt;
        int ret;
-       const char *category;
-       int is_watch;
 
        if (!slave_need_to_reactivate_instances(slave)) {
                DbgPrint("Do not need to reactivate instances\n");
                return 0;
        }
 
-       category = package_category(info);
-       is_watch = (category && strcmp(CATEGORY_WATCH_CLOCK, category) == 0);
-
        cnt = 0;
-       EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
-               if (is_watch) {
+       if (slave_is_watch(slave)) {
+               EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
                        /**
                         * @note
                         * Watch will be recovered by SLAVE_SYNC_HELLO command.
                         * Not from here.
                         */
                        instance_watch_set_need_to_recover(inst, EINA_TRUE);
-               } else {
+                       cnt++;
+               }
+               DbgPrint("Watch instance: %d\n", cnt);
+       } else {
+               EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
                        ret = instance_recover_state(inst);
                        if (!ret) {
                                continue;
                        }
 
                        instance_thaw_updator(inst);
+                       cnt++;
                }
-               cnt++;
        }
 
        DbgPrint("Recover state for %d instances of %s\n", cnt, package_name(info));
@@ -249,7 +248,7 @@ static int xmonitor_paused_cb(void *data)
        }
 
        EINA_LIST_FOREACH(info->inst_list, l, inst) {
-               instance_freeze_updator(inst);
+               (void)instance_freeze_updator(inst);
        }
 
        return 0;
@@ -279,7 +278,7 @@ static int slave_paused_cb(struct slave_node *slave, void *data)
        Eina_List *l;
 
        EINA_LIST_FOREACH(info->inst_list, l, inst) {
-               instance_freeze_updator(inst);
+               (void)instance_freeze_updator(inst);
        }
 
        return 0;
@@ -1162,6 +1161,7 @@ HAPI const char *package_category(const struct pkg_info *info)
 static inline int assign_new_slave(const char *slave_pkgname, struct pkg_info *info)
 {
        char *s_name;
+       const char *category;
 
        s_name = util_slavename();
        if (!s_name) {
@@ -1171,9 +1171,7 @@ static inline int assign_new_slave(const char *slave_pkgname, struct pkg_info *i
 
        DbgPrint("New slave[%s] is assigned for %s (using %s / abi[%s] / accel[%s]\n", s_name, info->widget_id, slave_pkgname, info->abi, info->hw_acceleration);
        info->slave = slave_create(s_name, info->secured, info->abi, slave_pkgname, info->network, info->hw_acceleration);
-
        DbgFree(s_name);
-
        if (!info->slave) {
                /*!
                 * \note
@@ -1184,6 +1182,16 @@ static inline int assign_new_slave(const char *slave_pkgname, struct pkg_info *i
                 */
                return WIDGET_ERROR_FAULT;
        }
+
+       slave_set_resource_limit(info->slave, 0u, 0u);
+
+       /**
+        * @note
+        * At the first time, the slave is created, "is_watch" will be initialized.
+        */
+       category = package_category(info);
+       slave_set_is_watch(info->slave, (category && strcmp(CATEGORY_WATCH_CLOCK, category) == 0));
+
        /*!
         * \note
         * Slave is not activated yet.
@@ -1751,31 +1759,4 @@ HAPI char *package_get_pkgid(const char *appid)
        return pkgid;
 }
 
-HAPI int package_del_instance_by_category(const char *category, const char *except_widget_id)
-{
-       Eina_List *l;
-       Eina_List *n;
-       Eina_List *m;
-       struct inst_info *inst;
-       struct pkg_info *info;
-       int ret;
-
-       EINA_LIST_FOREACH(s_info.pkg_list, m, info) {
-               ErrPrint("pkgid[%s] category [%s]\n", info->pkgid, info->category);
-               if (info->category && !strcmp(category, info->category)) {
-                       if (except_widget_id && !strcmp(package_name(info), except_widget_id)){
-                               ErrPrint("package_name[%s] widget_id[%s]\n", package_name(info), except_widget_id);
-                               continue;
-                       }
-
-                       EINA_LIST_FOREACH_SAFE(info->inst_list, l, n, inst) {
-                               ret = instance_destroy(inst, WIDGET_DESTROY_TYPE_DEFAULT);
-                               ErrPrint("instance_destroy return [%d]\n", ret);
-                       }
-               }
-       }
-
-       return WIDGET_ERROR_NONE;
-}
-
 /* End of a file */
index 23f81c9..dfded9c 100644 (file)
@@ -72,6 +72,8 @@
 #define ACCESS_TYPE_PREV 2
 #define ACCESS_TYPE_OFF 3
 
+#define PAGE_SIZE 4096
+
 #define aul_terminate_pid_async(a) aul_terminate_pid(a)
 
 struct sync_ctx_item {
@@ -171,8 +173,19 @@ static char *is_valid_slave(pid_t pid, const char *abi, const char *provider_pkg
        int verified;
 
        if (aul_app_get_pkgname_bypid(pid, pid_pkgname, sizeof(pid_pkgname)) != AUL_R_OK) {
-               ErrPrint("pid[%d] is not authroized provider package\n", pid);
-               return NULL;
+               if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
+                       DbgPrint("Debug mode is enabled: [%s] [%s]\n", abi, provider_pkgname);
+                       if (provider_pkgname) {
+                               strncpy(pid_pkgname, provider_pkgname, sizeof(pid_pkgname));
+                               DbgPrint("[%d]_pkgname is updated to [%s]\n", pid, pid_pkgname);
+                       } else {
+                               DbgPrint("There is no way to get the pkgname of %d even though we are in the debug mode\n", pid);
+                               return NULL;
+                       }
+               } else {
+                       ErrPrint("pid[%d] is not authroized provider package\n", pid);
+                       return NULL;
+               }
        }
 
        abi_pkgname = widget_abi_get_pkgname_by_abi(abi);
@@ -187,6 +200,9 @@ static char *is_valid_slave(pid_t pid, const char *abi, const char *provider_pkg
                 * In this case, we should believe its request.
                 */
                return strdup(provider_pkgname);
+       } else if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
+               DbgPrint("Debug mode is enabled, use the %s as a widget_id\n", provider_pkgname);
+               return provider_pkgname ? strdup(provider_pkgname) : NULL;
        }
 
        /*!
@@ -1396,6 +1412,7 @@ static struct packet *client_new(pid_t pid, int handle, const struct packet *pac
                goto out;
        }
        DbgFree(mainappid);
+       mainappid = NULL;
 
        info = package_find(widget_id);
        if (!info) {
@@ -5210,7 +5227,7 @@ static struct packet *client_widget_acquire_xpixmap(pid_t pid, int handle, const
        buf_ptr = buffer_handler_pixmap_ref(buffer);
        if (!buf_ptr) {
                ErrPrint("Failed to ref pixmap\n");
-               ret = WIDGET_ERROR_NOT_EXIST;
+               ret = WIDGET_ERROR_FAULT;
                goto out;
        }
 
@@ -5389,7 +5406,7 @@ static struct packet *client_gbar_acquire_xpixmap(pid_t pid, int handle, const s
 
        buffer = instance_gbar_extra_buffer(inst, idx);
        if (!buffer) {
-               ret = WIDGET_ERROR_NOT_EXIST;
+               ret = WIDGET_ERROR_FAULT;
                goto out;
        }
 
@@ -6652,20 +6669,26 @@ out:
        return NULL;
 }
 
-static inline __attribute__((always_inline)) struct slave_node *debug_mode_enabled(int pid, const char *slavename, const char *pkgname, int secured, const char *abi, const char *acceleration)
+static inline __attribute__((always_inline)) struct slave_node *debug_mode_enabled(struct slave_node *slave, int pid, const char *slavename, const char *pkgname, int secured, const char *abi, const char *acceleration)
 {
-       struct slave_node *slave;
-
-       slave = slave_find_by_pkgname(pkgname);
        if (!slave) {
-               slave = slave_create(slavename, secured, abi, pkgname, 0, acceleration);
-               if (!slave) {
-                       return NULL;
+               if (pkgname) {
+                       slave = slave_find_by_pkgname(pkgname);
                }
 
-               DbgPrint("New slave is created net(%d) abi(%s) secured(%d) accel(%s)\n", 0, abi, secured, acceleration);
-       } else {
-               DbgPrint("Registered slave is replaced with this new one\n");
+               if (!slave) {
+                       slave = slave_find_by_pid(pid);
+                       if (!slave) {
+                               slave = slave_create(slavename, secured, abi, pkgname, 0, acceleration);
+                               if (!slave) {
+                                       return NULL;
+                               }
+                       }
+
+                       DbgPrint("New slave is created net(%d) abi(%s) secured(%d) accel(%s)\n", 0, abi, secured, acceleration);
+               } else {
+                       DbgPrint("Registered slave is replaced with this new one\n");
+               }
        }
 
        slave_set_pid(slave, pid);
@@ -6677,7 +6700,8 @@ static inline __attribute__((always_inline)) struct slave_node *debug_mode_enabl
 
 static struct packet *slave_hello(pid_t pid, int handle, const struct packet *packet) /* slave_name, ret */
 {
-       char pkgname[pathconf("/", _PC_PATH_MAX)];
+       char _pkgname[pathconf("/", _PC_PATH_MAX)];
+       const char *pkgname = NULL;
        struct slave_node *slave;
        const char *acceleration;
        const char *slavename;
@@ -6702,19 +6726,41 @@ static struct packet *slave_hello(pid_t pid, int handle, const struct packet *pa
                slave = slave_find_by_pid(pid);
        }
 
-       if (aul_app_get_pkgname_bypid(pid, pkgname, sizeof(pkgname)) != AUL_R_OK) {
-               ErrPrint("pid[%d] is not authroized provider package, try to find it using its name[%s]\n", pid, slavename);
-               goto out;
+       if (aul_app_get_pkgname_bypid(pid, _pkgname, sizeof(_pkgname)) != AUL_R_OK) {
+               if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
+                       DbgPrint("Debug mode is enabled. could not determine the pkgname for %d\n", pid);
+               } else {
+                       ErrPrint("pid[%d] is not authroized provider package, try to find it using its name[%s]\n", pid, slavename);
+                       goto out;
+               }
+       } else {
+               pkgname = (const char *)_pkgname;
        }
 
        if (!slave) {
                if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
-                       slave = debug_mode_enabled(pid, slavename, pkgname, secured, abi, acceleration);
+                       /**
+                        * @note
+                        * In case of debugging mode,
+                        * Slave can be launched first even there are no instances.
+                        * If there is no slave object, the debug_mode_enabled function will create a slave object first.
+                        * So it can waiting service request of master.
+                        *
+                        * But if the slave is launched via valgrind or gdb,
+                        * the slave object cannot be created because the aul_app_get_pkgname_bypid will fails to get pkgname of given process.
+                        * "gdb" or "valgrind" pid is not exists in the package DB.
+                        */
+                       slave = debug_mode_enabled(slave, pid, slavename, pkgname, secured, abi, acceleration);
                        if (!slave) {
                                ErrPrint("Failed to create a new slave for %s\n", slavename);
                                goto out;
                        }
                } else {
+                       /**
+                        * @note
+                        * If the master is not in the debug mode,
+                        * terminate slave process if it sends connection request which is not authorized.
+                        */
                        ErrPrint("Request comes from unknown: %d\n", pid);
                        ret = aul_terminate_pid_async(pid);
                        DbgPrint("Terminate %d (%d)\n", pid, ret);
@@ -6722,7 +6768,7 @@ static struct packet *slave_hello(pid_t pid, int handle, const struct packet *pa
                }
        } else {
                if (slave_pid(slave) != pid) {
-                       if (slave_pid(slave) > 0 && !slave_extra_bundle_data(slave)) {
+                       if (slave_pid(slave) > 0 && !slave_extra_bundle_data(slave) && !(WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode)) {
                                ErrPrint("Slave(%s) is already assigned to %d\n", slave_name(slave), slave_pid(slave));
                                if (pid > 0) {
                                        ret = aul_terminate_pid_async(pid);
@@ -6742,8 +6788,13 @@ static struct packet *slave_hello(pid_t pid, int handle, const struct packet *pa
                                slave_set_valid(slave);
                                DbgFree(widget_id);
                        } else {
-                               ErrPrint("slave is not valid (%s)\n", pkgname);
-                               goto out;
+                               if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
+                                       DbgPrint("Forcely set to valid slave for debugging mode\n");
+                                       slave_set_valid(slave);
+                               } else {
+                                       ErrPrint("slave is not valid (%s)\n", pkgname);
+                                       goto out;
+                               }
                        }
                }
        }
@@ -6798,7 +6849,7 @@ static struct packet *slave_ping(pid_t pid, int handle, const struct packet *pac
        if (ret != 1) {
                ErrPrint("Parameter is not matched\n");
        } else {
-               slave_rpc_ping(slave);
+               (void)slave_rpc_ping(slave);
        }
 
 out:
@@ -7267,6 +7318,11 @@ static struct packet *slave_updated(pid_t pid, int handle, const struct packet *
                        break;
                }
 
+               /**
+                * @todo
+                * If the slave has direct connection with viewer,
+                * How could master detects its update and how could it be expanded?
+                */
                slave_give_more_ttl(slave);
        }
 
@@ -8005,7 +8061,8 @@ static void delete_ctx_cb(int handle, void *data)
 
 static struct packet *slave_hello_sync_prepare(pid_t pid, int handle, const struct packet *packet) /* slave_name, ret */
 {
-       char pkgname[pathconf("/", _PC_PATH_MAX)];
+       char _pkgname[pathconf("/", _PC_PATH_MAX)];
+       const char *pkgname = NULL;
        int ret;
        struct sync_ctx_item *ctx;
        double timestamp;
@@ -8018,17 +8075,27 @@ static struct packet *slave_hello_sync_prepare(pid_t pid, int handle, const stru
                goto out;
        }
 
-       if (aul_app_get_pkgname_bypid(pid, pkgname, sizeof(pkgname)) != AUL_R_OK) {
-               ErrPrint("pid[%d] is not authroized provider package, try to find it using its name\n", pid);
-               goto out;
+       if (aul_app_get_pkgname_bypid(pid, _pkgname, sizeof(_pkgname)) != AUL_R_OK) {
+               if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
+                       DbgPrint("Failed to get pkgname of %d\n", pid);
+               } else {
+                       ErrPrint("pid[%d] is not authroized provider package, try to find it using its name\n", pid);
+                       goto out;
+               }
+       } else {
+               pkgname = (const char *)_pkgname;
        }
 
        ctx = NULL;
        EINA_LIST_FOREACH_SAFE(s_info.hello_sync_ctx_list, l, n, ctx) {
                if (ctx->timestamp == timestamp) {
-                       if (strcmp(pkgname, ctx->pkgname)) {
-                               ErrPrint("timestamp is valid, but pkgname is not matched: %s <> %s\n", pkgname, ctx->pkgname);
-                               /* Go ahead */
+                       if (pkgname && ctx->pkgname) {
+                               if (strcmp(pkgname, ctx->pkgname)) {
+                                       ErrPrint("timestamp is valid, but pkgname is not matched: %s <> %s\n", pkgname, ctx->pkgname);
+                                       /* Go ahead */
+                               }
+                       } else {
+                               DbgPrint("Skip to pkgname comparison (%s <> %s)\n", pkgname, ctx->pkgname);
                        }
 
                        break;
@@ -8067,17 +8134,19 @@ static struct packet *slave_hello_sync_prepare(pid_t pid, int handle, const stru
 
                ctx->timestamp = timestamp;
 
-               ctx->pkgname = strdup(pkgname);
-               if (!ctx->pkgname) {
-                       ErrPrint("strdup: %d\n", errno);
-                       DbgFree(ctx);
-                       goto out;
+               if (pkgname) {
+                       ctx->pkgname = strdup(pkgname);
+                       if (!ctx->pkgname) {
+                               ErrPrint("strdup: %d\n", errno);
+                               DbgFree(ctx);
+                               goto out;
+                       }
                }
 
                ctx->pid = pid;
                ctx->handle = handle;
 
-               DbgPrint("Sync context created: %s\n", pkgname);
+               DbgPrint("Sync context created: %s (%d)\n", pkgname, pid);
                s_info.hello_sync_ctx_list = eina_list_append(s_info.hello_sync_ctx_list, ctx);
 
                if (dead_callback_add(handle, delete_ctx_cb, ctx) < 0) {
@@ -8119,8 +8188,9 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
        char *widget_id;
        int secured;
        int ret;
-       char pkgname[pathconf("/", _PC_PATH_MAX)];
+       char _pkgname[pathconf("/", _PC_PATH_MAX)];
        double timestamp;
+       const char *pkgname = NULL;
 
        ret = packet_get(packet, "dissss", &timestamp, &secured, &slavename, &slave_pkgname, &acceleration, &abi);
        if (ret != 6) {
@@ -8149,13 +8219,20 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                }
        }
 
-       if (aul_app_get_pkgname_bypid(pid, pkgname, sizeof(pkgname)) != AUL_R_OK) {
-               ErrPrint("pid[%d] is not authroized provider package, try to find it using its name[%s]\n", pid, slavename);
-               ret = WIDGET_ERROR_PERMISSION_DENIED;
-               goto out;
+       if (aul_app_get_pkgname_bypid(pid, _pkgname, sizeof(_pkgname)) != AUL_R_OK) {
+               if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
+                       pkgname = slave_pkgname;
+                       DbgPrint("Debug mode is enabled. could not determine the pkgname for %d use the slave_pkgname[%s]\n", pid, pkgname);
+               } else {
+                       ErrPrint("pid[%d] is not authroized provider package, try to find it using its name[%s]\n", pid, slavename);
+                       ret = WIDGET_ERROR_PERMISSION_DENIED;
+                       goto out;
+               }
+       } else {
+               pkgname = (const char *)_pkgname;
        }
 
-       if (slave || !(WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode)) {
+       if (slave) {
                struct sync_ctx_item *item;
                Eina_List *l;
                Eina_List *n;
@@ -8191,11 +8268,15 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                        item->pid = pid;
                        item->timestamp = timestamp;
 
-                       /**
-                        * @note
-                        * If the prepare sync doesn't come in ACTIVATE_TIME * 2.0f, there is a problem. we have to cancel it
-                        */
-                       item->prepare_sync_wait_timer = ecore_timer_add(WIDGET_CONF_SLAVE_ACTIVATE_TIME * 2.0f, prepare_sync_wait_cb, item);
+                       if (!(WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode)) {
+                               /**
+                                * @note
+                                * If the prepare sync doesn't come in ACTIVATE_TIME * 2.0f, there is a problem. we have to cancel it
+                                */
+                               item->prepare_sync_wait_timer = ecore_timer_add(WIDGET_CONF_SLAVE_ACTIVATE_TIME * 2.0f, prepare_sync_wait_cb, item);
+                       } else {
+                               DbgPrint("prepare sync wait timer is disabled for debugging\n");
+                       }
 
                        /**
                         * @note
@@ -8209,8 +8290,12 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                         */
                        handle = -1;
                } else {
-                       if (strcmp(item->pkgname, pkgname)) {
-                               ErrPrint("HELLO_SYNC is comes from different package: %s <> %s\n", item->pkgname, pkgname);
+                       if (item->pkgname) {
+                               if (strcmp(item->pkgname, pkgname)) {
+                                       ErrPrint("HELLO_SYNC is comes from different package: %s <> %s\n", item->pkgname, pkgname);
+                               }
+                       } else {
+                               DbgPrint("item->pkgname[%s]\n", item->pkgname);
                        }
 
                        handle = item->handle;
@@ -8228,7 +8313,7 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
 
        if (!slave) {
                if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
-                       slave = debug_mode_enabled(pid, slavename, pkgname, secured, abi, acceleration);
+                       slave = debug_mode_enabled(slave, pid, slavename, pkgname, secured, abi, acceleration);
                        if (!slave) {
                                ErrPrint("Failed to create a new slave for %s\n", slavename);
                                ret = WIDGET_ERROR_FAULT;
@@ -8245,13 +8330,18 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                int width, height;
                unsigned int widget_size;
                Eina_List *inst_list;
-               const char *category;
 
                widget_id = is_valid_slave(pid, abi, pkgname);
                if (!widget_id) {
                        goto out;
                }
 
+               if (!slave_is_watch(slave)) {
+                       ErrPrint("Slave is not watch(only watch can use hello_sync) [%s]\n", widget_id);
+                       DbgFree(widget_id);
+                       goto out;
+               }
+
                info = package_find(widget_id);
                if (!info) {
                        char *pkgid;
@@ -8262,31 +8352,28 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                                goto out;
                        }
 
+                       DbgPrint("Package information is not exists, create it for [%s]\n", widget_id);
                        info = package_create(pkgid, widget_id);
                        DbgFree(pkgid);
+
+                       DbgFree(widget_id);
+                       ret = WIDGET_ERROR_FAULT;
+                       goto out;
                }
 
-               /**
-                * Finding a created instance information
-                */
-               category = package_category(info);
                inst_list = package_instance_list(info);
-               /**
-                * We don't need to search the package information again from instance.
-                * Instance will be created by its package information.
-                * So if we know how the instance is created (From what package), then we just can use it.
-                */
-               DbgPrint("Instance Count: %d of %s\n", eina_list_count(inst_list), package_name(info));
                inst = eina_list_nth(inst_list, 0);
                if (!inst) {
-                       ErrPrint("No valid instance");
+                       ErrPrint("Instance is not available for [%s]\n", widget_id);
                        DbgFree(widget_id);
-                       ret = WIDGET_ERROR_NOT_EXIST;
+                       ret = WIDGET_ERROR_FAULT;
                        goto out;
                }
 
+               DbgPrint("[%s] Instance Count: %d\n", widget_id, eina_list_count(inst_list));
+
                if (slave_pid(slave) != pid) {
-                       if (slave_pid(slave) > 0) {
+                       if (slave_pid(slave) > 0 && !slave_extra_bundle_data(slave) && !(WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode)) {
                                CRITICAL_LOG("Slave(%s) is already assigned to %d\n", slave_name(slave), slave_pid(slave));
                                if (pid > 0) {
                                        ret = aul_terminate_pid_async(pid);
@@ -8296,25 +8383,12 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                                ret = WIDGET_ERROR_NOT_EXIST;
                                goto out;
                        }
-                       CRITICAL_LOG("PID of slave(%s) is updated (%d -> %d)\n", slave_name(slave), slave_pid(slave), pid);
+                       DbgPrint("PID of slave(%s) is updated (%d -> %d)\n", slave_name(slave), slave_pid(slave), pid);
                        slave_set_pid(slave, pid);
                }
 
                slave_set_valid(slave);
 
-               /**
-                * @TODO
-                * This should able to be configurable by .conf file.
-                * Watch instance can be created only ONE in this system.
-                */
-               if (strcmp(CATEGORY_WATCH_CLOCK, category) == 0) {
-                       /**
-                        * @note
-                        * If a new provider is watch app, destroy the old watch app instance
-                        */
-                       package_del_instance_by_category(CATEGORY_WATCH_CLOCK, widget_id);
-               }
-
                if (handle >= 0) {
                        slave_rpc_update_handle(slave, handle, 1);
 
@@ -8497,6 +8571,11 @@ static struct packet *service_get_inst_list(pid_t pid, int handle, const struct
                        int len;
                        int cnt = 0;
 
+                       if (size < 0) {
+                               ErrPrint("sysconf: %d\n", errno);
+                               size = PAGE_SIZE;
+                       }
+
                        id_buffer = malloc(size);
                        if (!id_buffer) {
                                result = packet_create_reply(packet, "iis", WIDGET_ERROR_OUT_OF_MEMORY, 0, NULL);
@@ -8509,7 +8588,13 @@ static struct packet *service_get_inst_list(pid_t pid, int handle, const struct
                                if (offset + len > size) {
                                        /* Expanding the ID_BUFFER */
                                        char *resized_buffer;
-                                       size += sysconf(_SC_PAGESIZE);
+                                       int more_size;
+                                       more_size = sysconf(_SC_PAGESIZE);
+                                       if (more_size < 0) {
+                                               ErrPrint("sysconf: %d\n", errno);
+                                               more_size = PAGE_SIZE;
+                                       }
+                                       size += more_size;
 
                                        DbgPrint("Expanding heap to %d\n", size);
 
index b06c508..65b300f 100644 (file)
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#define _GNU_SOURCE
 #include <stdio.h>
 #include <pthread.h>
 #include <secure_socket.h>
index b6ec4e7..58b2262 100644 (file)
@@ -118,6 +118,15 @@ struct slave_node {
        char *hw_acceleration;
        int valid;
        char *extra_bundle_data;
+
+       int is_watch;   /*!< Specialized field. Only for the WATCH */
+
+       struct _resource {
+               struct _memory {
+                       unsigned int soft;
+                       unsigned int hard;
+               } memory;
+       } resources;
 };
 
 struct event {
@@ -141,14 +150,36 @@ static struct {
        .deactivate_all_refcnt = 0,
 };
 
+static inline int apply_resource_limit(struct slave_node *slave)
+{
+       struct rlimit limit;
+       struct rlimit old_limit;
+
+       if (slave_pid(slave) <= 0 || (slave->resources.memory.soft == 0 && slave->resources.memory.hard == 0)) {
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
+       limit.rlim_cur = slave->resources.memory.soft;
+       limit.rlim_max = slave->resources.memory.hard;
+
+       if (prlimit(slave->pid, RLIMIT_AS, &limit, &old_limit) < 0) {
+               ErrPrint("prlimit: %d\n", errno);
+               return WIDGET_ERROR_FAULT;
+       }
+
+       DbgPrint("Old: %lu - %lu / %lu - %lu\n", limit.rlim_cur, limit.rlim_max, old_limit.rlim_cur, old_limit.rlim_max);
+
+       return WIDGET_ERROR_NONE;
+}
+
 static Eina_Bool terminate_timer_cb(void *data)
 {
        struct slave_node *slave = data;
        int ret;
 
-       /*!
-        * \todo
-        * check the return value of the aul_terminate_pid
+       /**
+        * @todo
+        * Check the return value of the aul_terminate_pid
         */
        slave->state = SLAVE_REQUEST_TO_TERMINATE;
        slave->terminate_timer = NULL;
@@ -202,9 +233,9 @@ static struct slave_node *slave_deactivate(struct slave_node *slave, int no_time
                (void)slave_rpc_disconnect(slave);
        } else if (slave->terminate_timer) {
                ErrPrint("Terminate timer is already fired (%d)\n", slave->pid);
-       } else if (!slave->extra_bundle_data && ((!no_timer && !slave->secured) || slave_is_app(slave))) {
+       } else if (!slave->extra_bundle_data && ((!no_timer && !slave->secured) || slave_is_app(slave)) && WIDGET_CONF_SLAVE_TERMINATE_TIME > 0.0f) {
                DbgPrint("Fire the terminate timer: %d (%d)\n", slave->pid, slave_is_app(slave));
-               slave->terminate_timer = ecore_timer_add(WIDGET_CONF_SLAVE_ACTIVATE_TIME, terminate_timer_cb, slave);
+               slave->terminate_timer = ecore_timer_add(WIDGET_CONF_SLAVE_TERMINATE_TIME, terminate_timer_cb, slave);
                if (!slave->terminate_timer) {
                        /*!
                         * \note
@@ -246,30 +277,40 @@ static struct slave_node *slave_deactivate(struct slave_node *slave, int no_time
 
 static Eina_Bool slave_ttl_cb(void *data)
 {
-       struct pkg_info *info;
        struct slave_node *slave = (struct slave_node *)data;
-       Eina_List *l;
-       Eina_List *pkg_list;
-
-       pkg_list = (Eina_List *)package_list();
-       EINA_LIST_FOREACH(pkg_list, l, info) {
-               if (package_slave(info) == slave) {
-                       struct inst_info *inst;
-                       Eina_List *inst_list;
-                       Eina_List *n;
-
-                       inst_list = (Eina_List *)package_instance_list(info);
-                       EINA_LIST_FOREACH(inst_list, n, inst) {
-                               if (instance_visible_state(inst) == WIDGET_SHOW) {
-                                       DbgPrint("Instance is in show, give more ttl to %d for %s\n", slave_pid(slave), instance_id(inst));
-                                       return ECORE_CALLBACK_RENEW;
+
+       if (slave_state(slave) != SLAVE_REQUEST_TO_PAUSE && slave_state(slave) != SLAVE_PAUSED) {
+               Eina_List *l;
+               Eina_List *pkg_list;
+               struct pkg_info *info;
+
+               /**
+                * @note
+                * If the slave is not paused,
+                * Should check all instances in this slave.
+                */
+               pkg_list = (Eina_List *)package_list();
+               EINA_LIST_FOREACH(pkg_list, l, info) {
+                       if (package_slave(info) == slave) {
+                               struct inst_info *inst;
+                               Eina_List *inst_list;
+                               Eina_List *n;
+
+                               inst_list = (Eina_List *)package_instance_list(info);
+                               EINA_LIST_FOREACH(inst_list, n, inst) {
+                                       if (instance_visible_state(inst) == WIDGET_SHOW) {
+                                               DbgPrint("Instance is in show, give more ttl to %d for %s\n", slave_pid(slave), instance_id(inst));
+                                               return ECORE_CALLBACK_RENEW;
+                                       }
                                }
                        }
-               }
+               } // EINA_LIST_FOREACH
+       } else {
+               DbgPrint("Slave is paused, Terminate it now\n");
        }
 
-       /*!
-        * \note
+       /**
+        * @note
         * ttl_timer must has to be set to NULL before deactivate the slave
         * It will be used for making decision of the expired TTL timer or the fault of a widget.
         */
@@ -456,7 +497,10 @@ HAPI int slave_expired_ttl(struct slave_node *slave)
                return 0;
        }
 
-       if (!slave_is_app(slave) && !slave->secured && !(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL)) {
+       if (!slave_is_app(slave)
+               && !slave->secured
+               && !(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL))
+       {
                return 0;
        }
 
@@ -510,6 +554,11 @@ HAPI struct slave_node *slave_create(const char *name, int is_secured, const cha
                return slave;
        }
 
+       if (!pkgname) {
+               ErrPrint("Slave pkgname is not valid[%s]\n", pkgname);
+               return NULL;
+       }
+
        slave = create_slave_node(name, is_secured, abi, pkgname, network, hw_acceleration);
        if (!slave) {
                return NULL;
@@ -878,10 +927,17 @@ HAPI int slave_give_more_ttl(struct slave_node *slave)
 {
        double delay;
 
-       if (!(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL) && ((!slave_is_app(slave) && !slave->secured) || !slave->ttl_timer)) {
+       if (!(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL)
+               && ((!slave_is_app(slave) && !slave->secured) || !slave->ttl_timer))
+       {
                return WIDGET_ERROR_INVALID_PARAMETER;
        }
 
+       if (WIDGET_CONF_FORCE_TO_TERMINATE) {
+               DbgPrint("Force to terminate is enabled: %s\n", slave_pkgname(slave));
+               return WIDGET_ERROR_DISABLED;
+       }
+
        delay = WIDGET_CONF_SLAVE_TTL - ecore_timer_pending_get(slave->ttl_timer);
        ecore_timer_delay(slave->ttl_timer, delay);
        return WIDGET_ERROR_NONE;
@@ -889,7 +945,9 @@ HAPI int slave_give_more_ttl(struct slave_node *slave)
 
 HAPI int slave_freeze_ttl(struct slave_node *slave)
 {
-       if (!(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL) && ((!slave_is_app(slave) && !slave->secured) || !slave->ttl_timer)) {
+       if (!(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL)
+               && ((!slave_is_app(slave) && !slave->secured) || !slave->ttl_timer))
+       {
                return WIDGET_ERROR_INVALID_PARAMETER;
        }
 
@@ -901,7 +959,9 @@ HAPI int slave_thaw_ttl(struct slave_node *slave)
 {
        double delay;
 
-       if (!(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL) && ((!slave_is_app(slave) && !slave->secured) || !slave->ttl_timer)) {
+       if (!(WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL)
+               && ((!slave_is_app(slave) && !slave->secured) || !slave->ttl_timer))
+       {
                return WIDGET_ERROR_INVALID_PARAMETER;
        }
 
@@ -931,7 +991,11 @@ HAPI int slave_activated(struct slave_node *slave)
         * 2. Service provider is "secured" and SLAVE_TTL is greater than 0.0f
         * 3. If a slave is launched for sdk_viewer (widget debugging), Do not activate TTL
         */
-       if (!slave->extra_bundle_data && ((WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL) || slave->secured == 1 || slave_is_app(slave)) && WIDGET_CONF_SLAVE_TTL > 0.0f) {
+       if (!slave->extra_bundle_data /* Launched by SDK Viewer */
+               && !slave_is_watch(slave) /* Not a watch */
+               && ((WIDGET_IS_INHOUSE(slave_abi(slave)) && WIDGET_CONF_SLAVE_LIMIT_TO_TTL) || slave->secured == 1 || slave_is_app(slave))
+               && WIDGET_CONF_SLAVE_TTL > 0.0f)
+       {
                DbgPrint("Slave deactivation timer is added (%s - %lf)\n", slave_name(slave), WIDGET_CONF_SLAVE_TTL);
                slave->ttl_timer = ecore_timer_add(WIDGET_CONF_SLAVE_TTL, slave_ttl_cb, slave);
                if (!slave->ttl_timer) {
@@ -965,6 +1029,7 @@ HAPI int slave_activated(struct slave_node *slave)
        }
 
        slave_set_priority(slave, LOW_PRIORITY);
+       (void)apply_resource_limit(slave);
        return WIDGET_ERROR_NONE;
 }
 
@@ -1506,6 +1571,10 @@ HAPI struct slave_node *slave_find_by_pkgname(const char *pkgname)
        Eina_List *l;
        struct slave_node *slave;
 
+       if (!pkgname) {
+               return NULL;
+       }
+
        EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
                if (!strcmp(slave_pkgname(slave), pkgname)) {
                        if (slave_pid(slave) == (pid_t)-1 || slave_pid(slave) == (pid_t)0) {
@@ -1686,7 +1755,7 @@ static void resume_cb(struct slave_node *slave, const struct packet *packet, voi
 
        if (ret == 0) {
                slave->state = SLAVE_RESUMED;
-               slave_rpc_ping_thaw(slave);
+               (void)slave_rpc_ping_thaw(slave);
                invoke_resumed_cb(slave);
        }
 }
@@ -1729,7 +1798,7 @@ static void pause_cb(struct slave_node *slave, const struct packet *packet, void
 
        if (ret == 0) {
                slave->state = SLAVE_PAUSED;
-               slave_rpc_ping_freeze(slave);
+               (void)slave_rpc_ping_freeze(slave);
                invoke_paused_cb(slave);
        }
 }
@@ -1880,27 +1949,28 @@ HAPI int slave_need_to_reactivate(struct slave_node *slave)
        int reactivate;
 
        if (!WIDGET_CONF_REACTIVATE_ON_PAUSE) {
-               Eina_List *pkg_list;
-               Eina_List *l;
-               struct pkg_info *info;
-
-               /**
-                * @TODO
-                * Check all instances on this slave, whether they are all paused or not.
-                */
-               pkg_list = (Eina_List *)package_list();
+               if (slave_is_watch(slave)) {
+                       /**
+                        * @note
+                        * If this slave serves WATCH-App, it must has to be reactivated.
+                        */
+                       DbgPrint("Watch should be activated anyway (%s)\n", slave_pkgname(slave));
+                       reactivate = 1;
+               } else {
+                       Eina_List *pkg_list;
+                       Eina_List *l;
+                       struct pkg_info *info;
 
-               reactivate = 0;
+                       /**
+                        * @TODO
+                        * Check all instances on this slave, whether they are all paused or not.
+                        */
+                       pkg_list = (Eina_List *)package_list();
 
-               EINA_LIST_FOREACH(pkg_list, l, info) {
-                       if (package_slave(info) == slave) {
-                               const char *category;
-                               int is_watch;
-                               
-                               category = package_category(info);
-                               is_watch = (category && strcmp(CATEGORY_WATCH_CLOCK, category) == 0);
+                       reactivate = 0;
 
-                               if (!is_watch) {
+                       EINA_LIST_FOREACH(pkg_list, l, info) {
+                               if (package_slave(info) == slave) {
                                        struct inst_info *inst;
                                        Eina_List *inst_list;
                                        Eina_List *n;
@@ -1911,11 +1981,6 @@ HAPI int slave_need_to_reactivate(struct slave_node *slave)
                                                        reactivate++;
                                                }
                                        }
-                               } else {
-                                       DbgPrint("Watch should be activated anyway (%s)\n", package_name(info));
-                                       reactivate = 1;
-                                       /* There is only one instance in this case, so we can break this loop */
-                                       break;
                                }
                        }
                }
@@ -2083,4 +2148,52 @@ HAPI const char *slave_extra_bundle_data(struct slave_node *slave)
        return slave ? slave->extra_bundle_data : NULL;
 }
 
+HAPI int slave_is_watch(struct slave_node *slave)
+{
+       return slave ? slave->is_watch : 0;
+}
+
+HAPI void slave_set_is_watch(struct slave_node *slave, int flag)
+{
+       if (!slave) {
+               return;
+       }
+
+       slave->is_watch = flag;
+}
+
+HAPI int slave_set_resource_limit(struct slave_node *slave, unsigned int soft, unsigned int hard)
+{
+       if (!slave) {
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
+       if (soft > hard) {
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
+       slave->resources.memory.soft = soft;
+       slave->resources.memory.hard = hard;
+
+       (void)apply_resource_limit(slave);
+       return WIDGET_ERROR_NONE;
+}
+
+HAPI int slave_get_resource_limit(struct slave_node *slave, unsigned int *soft, unsigned int *hard)
+{
+       if (!slave) {
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
+       if (soft) {
+               *soft = slave->resources.memory.soft;
+       }
+
+       if (hard) {
+               *hard = slave->resources.memory.hard;
+       }
+
+       return WIDGET_ERROR_NONE;
+}
+
 /* End of a file */
index 82102f2..78b4f2c 100644 (file)
@@ -521,9 +521,14 @@ HAPI int slave_rpc_update_handle(struct slave_node *slave, int handle, int delet
                ecore_timer_del(rpc->pong_timer);
        }
 
-       rpc->pong_timer = ecore_timer_add(WIDGET_CONF_DEFAULT_PING_TIME, ping_timeout_cb, slave);
-       if (!rpc->pong_timer) {
-               ErrPrint("Failed to add ping timer\n");
+       if (slave_extra_bundle_data(slave)) {
+               ErrPrint("Disable WATCHDOG for debugging\n");
+               rpc->pong_timer = NULL;
+       } else {
+               rpc->pong_timer = ecore_timer_add(WIDGET_CONF_DEFAULT_PING_TIME, ping_timeout_cb, slave);
+               if (!rpc->pong_timer) {
+                       ErrPrint("Failed to add ping timer\n");
+               }
        }
 
        /*!
@@ -639,6 +644,11 @@ HAPI int slave_rpc_ping(struct slave_node *slave)
                return WIDGET_ERROR_FAULT;
        }
 
+       if (!rpc->pong_timer) {
+               ErrPrint("Watchdog is not enabled\n");
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
        rpc->ping_count++;
        if (rpc->ping_count != rpc->next_ping_count) {
                ErrPrint("Ping count is not correct\n");
@@ -665,6 +675,11 @@ HAPI int slave_rpc_ping_freeze(struct slave_node *slave)
                return WIDGET_ERROR_FAULT;
        }
 
+       if (!rpc->pong_timer) {
+               ErrPrint("Watchdog is not enabled\n");
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
        ecore_timer_freeze(rpc->pong_timer);
        return WIDGET_ERROR_NONE;
 }
@@ -684,6 +699,11 @@ HAPI int slave_rpc_ping_thaw(struct slave_node *slave)
                return WIDGET_ERROR_FAULT;
        }
 
+       if (!rpc->pong_timer) {
+               ErrPrint("Watchdog is not enabled\n");
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
        ecore_timer_thaw(rpc->pong_timer);
        return WIDGET_ERROR_NONE;
 }
index 2e5f557..0144142 100644 (file)
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define _GNU_SOURCE
-
 #include <stdio.h>
 #include <sys/time.h>
 #include <string.h>
index 70e72a2..948b861 100644 (file)
@@ -1490,7 +1490,8 @@ static Eina_Bool input_cb(void *data, Ecore_Fd_Handler *fd_handler)
                                        cmd_buffer[0] = '\0';
                                        prompt(NULL);
                                } else {
-                                       strcpy(cmd_buffer, tmp);
+                                       strncpy(cmd_buffer, tmp, CMD_BUFFER_SIZE - 1);
+                                       cmd_buffer[CMD_BUFFER_SIZE - 1]  = '\0';
                                        idx = strlen(cmd_buffer);
                                        prompt(cmd_buffer);
                                }