#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) {
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 */
#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;
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 {
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", ×tamp);
+ 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;
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", ×tamp, &secured, &slavename, &acceleration, &abi);
+ if (ret != 5) {
ErrPrint("Parameter is not matched\n");
goto out;
}
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);
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);
}
inst = NULL;
}
+
if (!inst) {
ErrPrint("No valid instance");
DbgFree(widget_id);
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);
DbgFree(widget_id);
}
- s_info.hello_ctx.pid = -1;
- s_info.hello_ctx.handle = -1;
-
out:
return result;
}