Add hello sync context manager.
authorSung-jae Park <nicesj.park@samsung.com>
Mon, 30 Mar 2015 01:52:53 +0000 (10:52 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Mon, 30 Mar 2015 01:52:53 +0000 (10:52 +0900)
Prepare Sync & Hello Sync should be managed.
This patch will maintain it using timestamp.

[model] Redwood,Kiran,B3(Wearable)
[binary_type] AP
[customer] Docomo/Orange/ATT/Open
[issue#] N/A
[problem]
[cause]
[solution]
[team] HomeTF
[request]
[horizontal_expansion]

Change-Id: Icf48e2db8b6c120598d481de818ba2a995224471

include/dead_monitor.h
src/dead_monitor.c
src/server.c

index 96efa3b..52ebbe4 100644 (file)
@@ -16,5 +16,7 @@
 
 extern int dead_init(void);
 extern int dead_fini(void);
+extern int dead_callback_add(int handle, void (*dead_cb)(int handle, void *data), void *data);
+extern void *dead_callback_del(int handle, void (*dead_cb)(int handle, void *data));
 
 /* End of a file */
index b870e44..bb8ae59 100755 (executable)
@@ -24,6 +24,7 @@
 
 #include <Eina.h>
 #include <widget_service.h> /* destroy_type for instance.h */
+#include <widget_errno.h>
 
 #include "slave_life.h"
 #include "client_life.h"
 #include "liveinfo.h"
 #include "conf.h"
 
+struct cb_item {
+       int handle;
+       void (*dead_cb)(int handle, void *data);
+       void *data;
+};
+
+static struct info {
+       Eina_List *cb_list;
+} s_info = {
+       .cb_list = NULL,
+};
+
 static int evt_cb(int handle, void *data)
 {
        struct slave_node *slave;
        struct client_node *client;
        struct liveinfo *liveinfo;
+       struct cb_item *dead_item;
+       Eina_List *l;
+       Eina_List *n;
+
+       EINA_LIST_FOREACH_SAFE(s_info.cb_list, l, n, dead_item) {
+               if (dead_item->handle == handle) {
+                       dead_item->dead_cb(dead_item->handle, dead_item->data);
+                       break;
+               }
+       }
 
        slave = slave_find_by_rpc_handle(handle);
        if (slave) {
@@ -92,8 +115,60 @@ HAPI int dead_init(void)
 
 HAPI int dead_fini(void)
 {
+       struct cb_item *item;
+
        com_core_del_event_callback(CONNECTOR_DISCONNECTED, evt_cb, NULL);
+
+       EINA_LIST_FREE(s_info.cb_list, item) {
+               DbgFree(item);
+       }
+
+       return 0;
+}
+
+HAPI int dead_callback_add(int handle, void (*dead_cb)(int handle, void *data), void *data)
+{
+       struct cb_item *item;
+       Eina_List *l;
+
+       EINA_LIST_FOREACH(s_info.cb_list, l, item) {
+               if (item->handle == handle) {
+                       return WIDGET_STATUS_ERROR_EXIST;
+               }
+       }
+
+       item = malloc(sizeof(*item));
+       if (!item) {
+               return WIDGET_STATUS_ERROR_OUT_OF_MEMORY;
+       }
+
+       item->handle = handle;
+       item->dead_cb = dead_cb;
+       item->data = data;
+
+       s_info.cb_list = eina_list_append(s_info.cb_list, item);
        return 0;
 }
 
+HAPI void *dead_callback_del(int handle, void (*dead_cb)(int handle, void *data))
+{
+       struct cb_item *item;
+       Eina_List *l;
+       Eina_List *n;
+
+       EINA_LIST_FOREACH_SAFE(s_info.cb_list, l, n, item) {
+               if (item->handle == handle && item->dead_cb == dead_cb) {
+                       void *cbdata;
+
+                       s_info.cb_list = eina_list_remove(s_info.cb_list, item);
+                       cbdata = item->data;
+                       DbgFree(item);
+
+                       return cbdata;
+               }
+       }
+
+       return NULL;
+}
+
 /* End of a file */
index 686bec8..d5a99a0 100755 (executable)
@@ -54,6 +54,7 @@
 #include "liveinfo.h"
 #include "io.h"
 #include "event.h"
+#include "dead_monitor.h"
 
 #define GBAR_OPEN_MONITOR_TAG "gbar,open,monitor"
 #define GBAR_RESIZE_MONITOR_TAG "gbar,resize,monitor"
 #define ACCESS_TYPE_PREV 2
 #define ACCESS_TYPE_OFF 3
 
+struct sync_ctx_item {
+       int pid;
+       int handle;
+       char *pkgname;
+       double timestamp;
+};
+
 static struct info {
        int info_fd;
        int client_fd;
@@ -79,20 +87,14 @@ static struct info {
        int slave_fd;
        int remote_client_fd;
 
-       struct hello_context {
-               int pid;
-               int handle;
-       } hello_ctx;
+       Eina_List *hello_sync_ctx_list;
 } s_info = {
        .info_fd = -1,
        .client_fd = -1,
        .service_fd = -1,
        .slave_fd = -1,
        .remote_client_fd = -1,
-       .hello_ctx = {
-               .pid = -1,
-               .handle = -1,
-       },
+       .hello_sync_ctx_list = NULL,
 };
 
 struct access_info {
@@ -7830,29 +7832,61 @@ out:
        return result;
 }
 
+static void delete_ctx_cb(int handle, void *data)
+{
+       struct sync_ctx_item *ctx = data;
+
+       s_info.hello_sync_ctx_list = eina_list_remove(s_info.hello_sync_ctx_list, ctx);
+
+       if (ctx->handle != handle) {
+               ErrPrint("Context is not valid (%s)\n", ctx->pkgname);
+       }
+
+       DbgFree(ctx->pkgname);
+       DbgFree(ctx);
+}
+
 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)];
        int ret;
-       double timestamp;
+       struct sync_ctx_item *ctx;
 
-       if (s_info.hello_ctx.pid > 0) {
-               ErrPrint("Process [%d] sent hello sync prepare. but hello sync is not called.\n", s_info.hello_ctx.pid);
+       ctx = calloc(1, sizeof(*ctx));
+       if (!ctx) {
+               ErrPrint("calloc: %s\n", strerror(errno));
+               goto out;
        }
 
-       ret = packet_get(packet, "d", &timestamp);
+       ret = packet_get(packet, "d", &ctx->timestamp);
        if (ret != 1) {
+               DbgFree(ctx);
                ErrPrint("Parameter is not matched\n");
                goto out;
        }
 
        if (aul_app_get_pkgname_bypid(pid, pkgname, sizeof(pkgname)) != AUL_R_OK) {
+               DbgFree(ctx);
                ErrPrint("pid[%d] is not authroized provider package, try to find it using its name\n", pid);
                goto out;
        }
 
-       s_info.hello_ctx.pid = pid;
-       s_info.hello_ctx.handle = handle;
+       ctx->pkgname = strdup(pkgname);
+       if (!ctx->pkgname) {
+               ErrPrint("strdup: %s\n", strerror(errno));
+               DbgFree(ctx);
+               goto out;
+       }
+
+       ctx->pid = pid;
+       ctx->handle = handle;
+
+       DbgPrint("Sync context created: %s\n", pkgname);
+       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) {
+               ErrPrint("Failed to add dead callback\n");
+       }
 
 out:
        return NULL;
@@ -7869,9 +7903,10 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
        int secured;
        int ret;
        char pkgname[pathconf("/", _PC_PATH_MAX)];
+       double timestamp;
 
-       ret = packet_get(packet, "isss", &secured, &slavename, &acceleration, &abi);
-       if (ret != 4) {
+       ret = packet_get(packet, "disss", &timestamp, &secured, &slavename, &acceleration, &abi);
+       if (ret != 5) {
                ErrPrint("Parameter is not matched\n");
                goto out;
        }
@@ -7897,6 +7932,41 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                goto out;
        }
 
+       if (slave || !(WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode)) {
+               struct sync_ctx_item *item;
+               Eina_List *l;
+               Eina_List *n;
+
+               item = NULL;
+               EINA_LIST_FOREACH_SAFE(s_info.hello_sync_ctx_list, l, n, item) {
+                       if (item->timestamp == timestamp && item->pid == pid) {
+                               s_info.hello_sync_ctx_list = eina_list_remove(s_info.hello_sync_ctx_list, item);
+                               break;
+                       }
+                       item = NULL;
+               }
+
+               if (!item) {
+                       ErrPrint("There is no such sync context (%d)\n", pid);
+                       goto out;
+               }
+
+               if (strcmp(item->pkgname, pkgname)) {
+                       ErrPrint("HELLO_SYNC is comes from different package: %s <> %s\n", item->pkgname, pkgname);
+               }
+
+               handle = item->handle;
+
+               if (dead_callback_del(handle, delete_ctx_cb) != item) {
+                       ErrPrint("Dead callback is not valid\n");
+               }
+
+               DbgFree(item->pkgname);
+               DbgFree(item);
+
+               DbgPrint("Hello sync context found: %s\n", pkgname);
+       }
+
        if (!slave) {
                if (WIDGET_CONF_DEBUG_MODE || g_conf.debug_mode) {
                        slave = slave_find_by_pkgname(pkgname);
@@ -7988,15 +8058,12 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                        slave_set_pid(slave, pid);
                        slave_set_valid(slave);
 
-                       if (s_info.hello_ctx.pid == pid) {
-                               /**
-                                * @note
-                                * Delete all pending packets
-                                */
-                               slave_rpc_update_handle(slave, s_info.hello_ctx.handle, 1);
-                       } else {
-                               ErrPrint("slave_hello pid[%d] != pid[%d]", s_info.hello_ctx.pid,pid);
-                       }
+                       /**
+                        * @note
+                        * In this case, there could not be exists any pended packets.
+                        * But we tried to clear them for a case!
+                        */
+                       slave_rpc_update_handle(slave, handle, 1);
 
                        DbgPrint("Slave is activated by request: %d (%s)/(%s)\n", pid, pkgname, slavename);
 
@@ -8057,6 +8124,7 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                        }
                        inst = NULL;
                }
+
                if (!inst) {
                        ErrPrint("No valid instance");
                        DbgFree(widget_id);
@@ -8087,11 +8155,7 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                        package_del_instance_by_category(CATEGORY_WATCH_CLOCK, widget_id);
                }
 
-               if (s_info.hello_ctx.pid == pid) {
-                       slave_rpc_update_handle(slave, s_info.hello_ctx.handle, 0);
-               } else {
-                       ErrPrint("slave_hello pid[%d] != pid[%d]", s_info.hello_ctx.pid, pid);
-               }
+               slave_rpc_update_handle(slave, handle, 0);
 
                DbgPrint("Slave is activated by request: %d (%s)/(%s)\n", pid, pkgname, slavename);
                widget_size = package_size_list(info);
@@ -8110,9 +8174,6 @@ static struct packet *slave_hello_sync(pid_t pid, int handle, const struct packe
                DbgFree(widget_id);
        }
 
-       s_info.hello_ctx.pid = -1;
-       s_info.hello_ctx.handle = -1;
-
 out:
        return result;
 }