summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung-jae Park <nicesj.park@samsung.com>2013-08-05 12:40:21 (GMT)
committerSung-jae Park <nicesj.park@samsung.com>2013-08-05 13:52:50 (GMT)
commit6aba37b1a1674a78e2215c6ab399d1a0bfea846f (patch)
treec4e7ece6548613193f5d6e4683df07abc6aaa3c7
parent2bdbbfa0fff90324d24bcbaf7753f1309d2e119e (diff)
downloaddata-provider-master-6aba37b1a1674a78e2215c6ab399d1a0bfea846f.zip
data-provider-master-6aba37b1a1674a78e2215c6ab399d1a0bfea846f.tar.gz
data-provider-master-6aba37b1a1674a78e2215c6ab399d1a0bfea846f.tar.bz2
Remote client service is implemented.
But not yet published. Slave Life cycle management code is updated. (Return value handling codes are updated) Change-Id: I8670b9502c11dce404b5a42db6e00fc31dbbdbe4
-rw-r--r--CMakeLists.txt3
-rw-r--r--include/buffer_handler.h9
-rw-r--r--include/client_life.h2
-rw-r--r--include/conf.h4
-rw-r--r--include/file_service.h20
-rw-r--r--include/service_common.h1
-rw-r--r--packaging/data-provider-master.spec15
-rw-r--r--src/buffer_handler.c176
-rw-r--r--src/client_life.c11
-rw-r--r--src/client_rpc.c7
-rw-r--r--src/conf.c23
-rw-r--r--src/critical_log.c10
-rw-r--r--src/file_service.c702
-rw-r--r--src/main.c6
-rw-r--r--src/server.c148
-rw-r--r--src/service_common.c114
-rw-r--r--src/shortcut_service.c5
-rw-r--r--src/slave_life.c154
-rw-r--r--src/utility_service.c4
-rw-r--r--src/xmonitor.c2
20 files changed, 1287 insertions, 129 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d5c7722..db98c32 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -60,6 +60,8 @@ ADD_DEFINITIONS("-DSHORTCUT_SMACK_LABEL=\"data-provider-master::shortcut\"")
ADD_DEFINITIONS("-DNOTIFICATION_SMACK_LABEL=\"data-provider-master::notification\"")
ADD_DEFINITIONS("-DBADGE_SMACK_LABEL=\"data-provider-master::badge\"")
+ADD_DEFINITIONS("-DCLIENT_PORT=\"8208\"")
+
ADD_DEFINITIONS("-DNDEBUG")
#ADD_DEFINITIONS("-DFLOG")
ADD_DEFINITIONS(${pkg_CFLAGS})
@@ -96,6 +98,7 @@ ADD_EXECUTABLE(${PROJECT_NAME}
src/notification_service.c
src/utility_service.c
src/service_common.c
+ src/file_service.c
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkg_LDFLAGS} "-ldl")
diff --git a/include/buffer_handler.h b/include/buffer_handler.h
index c2084cd..a60c59a 100644
--- a/include/buffer_handler.h
+++ b/include/buffer_handler.h
@@ -16,6 +16,7 @@
struct buffer_info;
struct inst_info;
+struct buffer;
enum buffer_type { /*!< Must have to be sync with libprovider, liblivebox-viewer */
BUFFER_TYPE_FILE,
@@ -159,4 +160,12 @@ extern void *buffer_handler_pixmap_buffer(struct buffer_info *info);
extern struct inst_info *buffer_handler_instance(struct buffer_info *info);
+extern struct buffer *buffer_handler_raw_open(enum buffer_type, void *resource);
+
+extern int buffer_handler_raw_close(struct buffer *buffer);
+
+extern void *buffer_handler_raw_data(struct buffer *buffer);
+
+extern int buffer_handler_raw_size(struct buffer *buffer);
+
/* End of a file */
diff --git a/include/client_life.h b/include/client_life.h
index 83e1899..fa88612 100644
--- a/include/client_life.h
+++ b/include/client_life.h
@@ -66,8 +66,6 @@ extern struct client_node *client_deactivated_by_fault(struct client_node *clien
extern void client_reset_fault(struct client_node *client);
extern const int const client_is_faulted(const struct client_node *client);
-extern const int const client_is_activated(const struct client_node *client);
-
/*!
* \note
* For other components which wants to know the state of a client
diff --git a/include/conf.h b/include/conf.h
index 714d3a2..2cc2f2b 100644
--- a/include/conf.h
+++ b/include/conf.h
@@ -49,6 +49,8 @@ struct conf {
double slave_ttl;
double slave_activate_time;
+ double slave_relaunch_time;
+ int slave_relaunch_count;
int max_log_line;
int max_log_file;
@@ -140,6 +142,8 @@ extern int conf_loader(void);
#define REPLACE_TAG_APPID g_conf.replace_tag
#define SLAVE_TTL g_conf.slave_ttl
#define SLAVE_ACTIVATE_TIME g_conf.slave_activate_time
+#define SLAVE_RELAUNCH_TIME g_conf.slave_relaunch_time
+#define SLAVE_RELAUNCH_COUNT g_conf.slave_relaunch_count
#define MAX_LOG_LINE g_conf.max_log_line
#define MAX_LOG_FILE g_conf.max_log_file
diff --git a/include/file_service.h b/include/file_service.h
new file mode 100644
index 0000000..208f739
--- /dev/null
+++ b/include/file_service.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2013 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+extern int file_service_init(void);
+extern int file_service_fini(void);
+
+/* End of a file */
diff --git a/include/service_common.h b/include/service_common.h
index 9cc0885..e60de2b 100644
--- a/include/service_common.h
+++ b/include/service_common.h
@@ -27,6 +27,7 @@ extern int tcb_fd(struct tcb *tcb);
extern struct service_context *tcb_svc_ctx(struct tcb *tcb);
extern int tcb_client_type(struct tcb *tcb);
extern int tcb_client_type_set(struct tcb *tcb, enum tcb_type type);
+extern int tcb_is_valid(struct service_context *svc_ctx, struct tcb *tcb);
extern struct service_context *service_common_create(const char *addr, int (*service_thread_main)(struct tcb *tcb, struct packet *packet, void *data), void *data);
extern int service_common_destroy(struct service_context *svc_ctx);
diff --git a/packaging/data-provider-master.spec b/packaging/data-provider-master.spec
index 26017ad..e74fad7 100644
--- a/packaging/data-provider-master.spec
+++ b/packaging/data-provider-master.spec
@@ -1,6 +1,6 @@
Name: data-provider-master
Summary: Master service provider for liveboxes.
-Version: 0.24.23
+Version: 0.25.2
Release: 1
Group: HomeTF/Livebox
License: Flora License
@@ -48,7 +48,17 @@ Keep trace on the life-cycle of the livebox and status of the service providers,
%setup -q
%build
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DPRODUCT=private
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS="${CFLAGS} -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS="${CXXFLAGS} -DTIZEN_ENGINEER_MODE"
+export FFLAGS="${FFLAGS} -DTIZEN_ENGINEER_MODE"
+%endif
+
+%if 0%{?sec_product_feature_livebox_shm}
+ cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DPRODUCT=baltic
+%else
+ cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DPRODUCT=private
+%endif
CFLAGS="${CFLAGS} -Wall -Winline -Werror" LDFLAGS="${LDFLAGS}" make %{?jobs:-j%jobs}
@@ -101,6 +111,7 @@ chmod 640 /opt/dbspace/.livebox.db
chown 0:5000 /opt/dbspace/.livebox.db-journal
chmod 640 /opt/dbspace/.livebox.db-journal
vconftool set -t bool "memory/data-provider-master/started" 0 -i -u 5000 -f -s system::vconf_system
+vconftool set -t string "db/data-provider-master/serveraddr" "/opt/usr/share/live_magazine/.client.socket" -i -u 5000 -f -s system::vconf_system
echo "Successfully installed. Please start a daemon again manually"
echo "%{_sysconfdir}/init.d/data-provider-master start"
diff --git a/src/buffer_handler.c b/src/buffer_handler.c
index 7d67b6a..ea35e84 100644
--- a/src/buffer_handler.c
+++ b/src/buffer_handler.c
@@ -517,7 +517,7 @@ static inline int load_shm_buffer(struct buffer_info *info)
buffer->type = BUFFER_TYPE_SHM;
buffer->refcnt = id;
buffer->state = CREATED; /*!< Needless */
- buffer->info = NULL; /*!< This has not to be used, every process will see this. So, don't try to save anything on here */
+ buffer->info = (void *)size; /*!< Use this field to indicates the size of SHM */
len = strlen(SCHEMA_SHM) + 30; /* strlen("shm://") + 30 */
@@ -1327,4 +1327,178 @@ HAPI int buffer_handler_fini(void)
return LB_STATUS_SUCCESS;
}
+static inline struct buffer *raw_open_file(const char *filename)
+{
+ struct buffer *buffer;
+ int fd;
+ off_t off;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ ErrPrint("open: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ off = lseek(fd, 0L, SEEK_END);
+ if (off == (off_t)-1) {
+ ErrPrint("lseek: %s\n", strerror(errno));
+
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
+
+ return NULL;
+ }
+
+ if (lseek(fd, 0L, SEEK_SET) == (off_t)-1) {
+ ErrPrint("lseek: %s\n", strerror(errno));
+
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
+
+ return NULL;
+ }
+
+ buffer = calloc(1, sizeof(*buffer) + off);
+ if (!buffer) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
+
+ return NULL;
+ }
+
+ buffer->state = CREATED;
+ buffer->type = BUFFER_TYPE_FILE;
+ buffer->refcnt = 0;
+ buffer->info = (void *)off;
+
+ if (read(fd, buffer->data, off) < 0) {
+ ErrPrint("read: %s\n", strerror(errno));
+ free(buffer);
+
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
+
+ return NULL;
+ }
+
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
+
+ return buffer;
+}
+
+static inline int raw_close_file(struct buffer *buffer)
+{
+ free(buffer);
+ return 0;
+}
+
+static inline struct buffer *raw_open_shm(int shm)
+{
+ struct buffer *buffer;
+
+ buffer = (struct buffer *)shmat(shm, NULL, SHM_RDONLY);
+ if (buffer == (struct buffer *)-1) {
+ ErrPrint("shmat: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ return buffer;
+}
+
+static inline int raw_close_shm(struct buffer *buffer)
+{
+ int ret;
+
+ ret = shmdt(buffer);
+ if (ret < 0)
+ ErrPrint("shmdt: %s\n", strerror(errno));
+
+ return ret;
+}
+
+static inline struct buffer *raw_open_pixmap(unsigned int pixmap)
+{
+ struct buffer *buffer;
+
+ buffer = calloc(1, sizeof(*buffer) + sizeof(int));
+ if (!buffer) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ buffer->state = CREATED;
+ buffer->type = BUFFER_TYPE_PIXMAP;
+
+ return buffer;
+}
+
+static inline int raw_close_pixmap(struct buffer *buffer)
+{
+ free(buffer);
+ return 0;
+}
+
+HAPI void *buffer_handler_raw_data(struct buffer *buffer)
+{
+ if (!buffer || buffer->state != CREATED)
+ return NULL;
+
+ return buffer->data;
+}
+
+HAPI int buffer_handler_raw_size(struct buffer *buffer)
+{
+ if (!buffer || buffer->state != CREATED)
+ return -EINVAL;
+
+ return (int)buffer->info;
+}
+
+HAPI struct buffer *buffer_handler_raw_open(enum buffer_type buffer_type, void *resource)
+{
+ struct buffer *handle;
+
+ switch (buffer_type) {
+ case BUFFER_TYPE_SHM:
+ handle = raw_open_shm((int)resource);
+ break;
+ case BUFFER_TYPE_FILE:
+ handle = raw_open_file(resource);
+ break;
+ case BUFFER_TYPE_PIXMAP:
+ handle = raw_open_pixmap((unsigned int)resource);
+ break;
+ default:
+ handle = NULL;
+ break;
+ }
+
+ return handle;
+}
+
+HAPI int buffer_handler_raw_close(struct buffer *buffer)
+{
+ int ret;
+
+ switch (buffer->type) {
+ case BUFFER_TYPE_SHM:
+ ret = raw_close_shm(buffer);
+ break;
+ case BUFFER_TYPE_FILE:
+ ret = raw_close_file(buffer);
+ break;
+ case BUFFER_TYPE_PIXMAP:
+ ret = raw_close_pixmap(buffer);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
/* End of a file */
diff --git a/src/client_life.c b/src/client_life.c
index 64c9920..32caae2 100644
--- a/src/client_life.c
+++ b/src/client_life.c
@@ -252,9 +252,9 @@ HAPI struct client_node *client_create(pid_t pid, int handle)
struct client_node *client;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (client) {
- ErrPrint("Client %d is already exists\n", pid);
+ ErrPrint("Client %d(%d) is already exists\n", pid, handle);
return client;
}
@@ -594,11 +594,6 @@ HAPI void client_fini(void)
}
}
-HAPI const int const client_is_activated(const struct client_node *client)
-{
- return client ? (client->pid != (pid_t)-1) : 1;
-}
-
HAPI int client_global_event_handler_add(enum client_global_event event_type, int (*cb)(struct client_node *client, void *data), void *data)
{
struct global_event_handler *handler;
@@ -774,7 +769,7 @@ HAPI int client_broadcast(struct inst_info *inst, struct packet *packet)
list = inst ? instance_client_list(inst) : s_info.client_list;
EINA_LIST_FOREACH(list, l, client) {
- if (client_pid(client) < 0) {
+ if (client_pid(client) == -1) {
ErrPrint("Client[%p] has PID[%d]\n", client, client_pid(client));
continue;
}
diff --git a/src/client_rpc.c b/src/client_rpc.c
index 78ca437..6276b99 100644
--- a/src/client_rpc.c
+++ b/src/client_rpc.c
@@ -116,11 +116,6 @@ static Eina_Bool command_consumer_cb(void *data)
goto out;
}
- if (!client_is_activated(command->client)) {
- ErrPrint("Client[%p] is not activated, destroy this command\n", command->client);
- goto out;
- }
-
if (client_is_faulted(command->client)) {
ErrPrint("Client[%p] is faulted, discard command\n", command->client);
goto out;
@@ -128,7 +123,7 @@ static Eina_Bool command_consumer_cb(void *data)
rpc = client_data(command->client, RPC_TAG);
if (!rpc) {
- ErrPrint("Invalid command\n");
+ ErrPrint("Client is not activated\n");
goto out;
}
diff --git a/src/conf.c b/src/conf.c
index 5ff4739..e86b3f9 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -56,6 +56,8 @@ HAPI struct conf g_conf = {
.slave_ttl = 30.0f,
.slave_activate_time = 30.0f,
+ .slave_relaunch_time = 3.0f,
+ .slave_relaunch_count = 3,
.max_log_line = 1000,
.max_log_file = 3,
@@ -224,6 +226,19 @@ static void slave_activate_time_handler(char *buffer)
DbgPrint("Slave activate time: %lf\n", g_conf.slave_activate_time);
}
+static void slave_relaunch_time_handler(char *buffer)
+{
+ if (sscanf(buffer, "%lf", &g_conf.slave_relaunch_time) != 1)
+ ErrPrint("Failed to parse the slave_activate_time\n");
+ DbgPrint("Slave relaunch time: %lf\n", g_conf.slave_relaunch_time);
+}
+
+static void slave_relaunch_count_handler(char *buffer)
+{
+ if (sscanf(buffer, "%d", &g_conf.slave_relaunch_count) != 1)
+ ErrPrint("Failed to parse the max_log_line\n");
+}
+
static void max_log_line_handler(char *buffer)
{
if (sscanf(buffer, "%d", &g_conf.max_log_line) != 1)
@@ -391,6 +406,14 @@ HAPI int conf_loader(void)
.handler = slave_activate_time_handler,
},
{
+ .name = "slave_relaunch_time",
+ .handler = slave_relaunch_time_handler,
+ },
+ {
+ .name = "slave_relaunch_count",
+ .handler = slave_relaunch_count_handler,
+ },
+ {
.name = "max_log_line",
.handler = max_log_line_handler,
},
diff --git a/src/critical_log.c b/src/critical_log.c
index 75a9796..9d3eb39 100644
--- a/src/critical_log.c
+++ b/src/critical_log.c
@@ -86,14 +86,11 @@ HAPI int critical_log(const char *func, int line, const char *fmt, ...)
{
va_list ap;
int ret;
- int status;
if (!s_info.fp)
return LB_STATUS_ERROR_IO;
- status = pthread_mutex_lock(&s_info.cri_lock);
- if (status != 0)
- ErrPrint("lock: %s\n", strerror(status));
+ CRITICAL_SECTION_BEGIN(&s_info.cri_lock);
fprintf(s_info.fp, "%lf [%s:%d] ", util_timestamp(), util_basename((char *)func), line);
@@ -106,10 +103,7 @@ HAPI int critical_log(const char *func, int line, const char *fmt, ...)
s_info.nr_of_lines++;
rotate_log();
- status = pthread_mutex_unlock(&s_info.cri_lock);
- if (status != 0)
- ErrPrint("unlock: %s\n", strerror(status));
-
+ CRITICAL_SECTION_END(&s_info.cri_lock);
return ret;
}
diff --git a/src/file_service.c b/src/file_service.c
new file mode 100644
index 0000000..15c2304
--- /dev/null
+++ b/src/file_service.c
@@ -0,0 +1,702 @@
+/*
+ * Copyright 2013 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <Eina.h>
+
+#include <dlog.h>
+
+#include <livebox-errno.h>
+#include <packet.h>
+#include <com-core.h>
+
+#include "file_service.h"
+#include "service_common.h"
+#include "debug.h"
+#include "util.h"
+#include "conf.h"
+#include "buffer_handler.h"
+
+#define FILE_SERVICE_ADDR "remote://:8209"
+#define FILE_PUSH_ADDR "remote://:8210"
+
+#define PUSH_EXIT 'e'
+#define PUSH_ITEM 'i'
+
+#define PKT_CHUNKSZ 4096
+
+static struct info {
+ struct service_context *svc_ctx;
+
+ pthread_t push_thid;
+
+ Eina_List *request_list;
+ pthread_mutex_t request_list_lock;
+
+ int request_pipe[PIPE_MAX];
+} s_info = {
+ .svc_ctx = NULL,
+ .request_list = NULL,
+ .request_list_lock = PTHREAD_MUTEX_INITIALIZER,
+ .request_pipe = { 0, },
+};
+
+struct request_item {
+ enum {
+ REQUEST_TYPE_FILE = 0x00,
+ REQUEST_TYPE_SHM = 0x01,
+ REQUEST_TYPE_PIXMAP = 0x02,
+ REQUEST_TYPE_MAX = 0x02,
+ } type;
+ union {
+ char *filename;
+ int shm;
+ unsigned int pixmap;
+ } data;
+ struct tcb *tcb;
+};
+
+typedef int (*send_data_func_t)(int fd, const struct request_item *item);
+
+/*!
+ * File transfer header.
+ * This must should be shared with client.
+ */
+struct burst_head {
+ off_t size;
+ int flen;
+ char fname[];
+};
+
+struct burst_data {
+ int size;
+ char data[];
+};
+
+static inline struct request_item *create_request_item(struct tcb *tcb, int type, void *data)
+{
+ struct request_item *item;
+
+ item = malloc(sizeof(*item));
+ if (!item) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ switch (type) {
+ case REQUEST_TYPE_FILE:
+ item->data.filename = strdup(data);
+ if (!item->data.filename) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ free(item);
+ return NULL;
+ }
+ break;
+ case REQUEST_TYPE_PIXMAP:
+ item->data.pixmap = (unsigned int)data;
+ break;
+ case REQUEST_TYPE_SHM:
+ item->data.shm = (int)data;
+ break;
+ default:
+ return NULL;
+ }
+
+ item->type = type;
+ item->tcb = tcb;
+ return item;
+}
+
+static inline int destroy_request_item(struct request_item *item)
+{
+ switch (item->type) {
+ case REQUEST_TYPE_FILE:
+ free(item->data.filename);
+ break;
+ case REQUEST_TYPE_SHM:
+ case REQUEST_TYPE_PIXMAP:
+ break;
+ default:
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ free(item);
+ return LB_STATUS_SUCCESS;
+}
+
+static int request_file_handler(struct tcb *tcb, struct packet *packet, struct request_item **item)
+{
+ const char *filename;
+
+ if (packet_get(packet, "s", &filename) != 1) {
+ ErrPrint("Invalid packet\n");
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ *item = create_request_item(tcb, REQUEST_TYPE_FILE, (void *)filename);
+ return *item ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_MEMORY;
+}
+
+static int request_pixmap_handler(struct tcb *tcb, struct packet *packet, struct request_item **item)
+{
+ unsigned int pixmap;
+
+ if (packet_get(packet, "i", &pixmap) != 1) {
+ ErrPrint("Invalid packet\n");
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ if (pixmap == 0) {
+ ErrPrint("pixmap is not valid\n");
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ /*!
+ * \TODO
+ * Attach to pixmap and copy its data to the client
+ */
+ *item = create_request_item(tcb, REQUEST_TYPE_PIXMAP, (void *)pixmap);
+ return *item ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_MEMORY;
+}
+
+static int request_shm_handler(struct tcb *tcb, struct packet *packet, struct request_item **item)
+{
+ int shm;
+
+ if (packet_get(packet, "i", &shm) != 1) {
+ ErrPrint("Invalid packet\n");
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ if (shm < 0) {
+ ErrPrint("shm is not valid: %d\n", shm);
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ /*!
+ * \TODO
+ * Attach to SHM and copy its buffer to the client
+ */
+ *item = create_request_item(tcb, REQUEST_TYPE_SHM, (void *)shm);
+ return *item ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_MEMORY;
+}
+
+/* SERVER THREAD */
+static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
+{
+ const char *cmd;
+ char ch = PUSH_ITEM;
+ int ret;
+ int i;
+ struct request_item *item;
+ struct packet *reply;
+ struct {
+ const char *cmd;
+ int (*request_handler)(struct tcb *tcb, struct packet *packet, struct request_item **item);
+ } cmd_table[] = {
+ {
+ .cmd = "request,file",
+ .request_handler = request_file_handler,
+ },
+ {
+ .cmd = "request,pixmap",
+ .request_handler = request_pixmap_handler,
+ },
+ {
+ .cmd = "request,shm",
+ .request_handler = request_shm_handler,
+ },
+ {
+ .cmd = NULL,
+ .request_handler = NULL,
+ },
+ };
+
+ if (!packet) {
+ DbgPrint("TCB %p is disconnected\n", tcb);
+ return LB_STATUS_SUCCESS;
+ }
+
+ cmd = packet_command(packet);
+ if (!cmd) {
+ ErrPrint("Invalid packet. cmd is not valid\n");
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ switch (packet_type(packet)) {
+ case PACKET_REQ:
+ for (i = 0; cmd_table[i].cmd; i++) {
+ /*!
+ * Protocol sequence
+ * FILE REQUEST COMMAND (Client -> Server)
+ * REPLY FOR REQUEST (Client <- Server)
+ * PUSH FILE (Client <- Server)
+ *
+ * Client & Server must has to keep this communication sequence.
+ */
+ if (strcmp(cmd, cmd_table[i].cmd))
+ continue;
+
+ item = NULL;
+ ret = cmd_table[i].request_handler(tcb, packet, &item);
+
+ reply = packet_create_reply(packet, "i", ret);
+ if (!reply) {
+ ErrPrint("Failed to create a reply packet\n");
+ break;
+ }
+
+ if (service_common_unicast_packet(tcb, reply) < 0)
+ ErrPrint("Unable to send reply packet\n");
+
+ packet_destroy(reply);
+
+ /*!
+ * \note
+ * After send the reply packet, file push thread can sending a file
+ */
+ if (ret != LB_STATUS_SUCCESS || !item)
+ break;
+
+ CRITICAL_SECTION_BEGIN(&s_info.request_list_lock);
+ s_info.request_list = eina_list_append(s_info.request_list, item);
+ CRITICAL_SECTION_END(&s_info.request_list_lock);
+
+ ret = write(s_info.request_pipe[PIPE_WRITE], &ch, sizeof(ch));
+ if (ret < 0) {
+ ErrPrint("write: %s\n", strerror(errno));
+
+ CRITICAL_SECTION_BEGIN(&s_info.request_list_lock);
+ s_info.request_list = eina_list_remove(s_info.request_list, item);
+ CRITICAL_SECTION_END(&s_info.request_list_lock);
+
+ destroy_request_item(item);
+ /*!
+ * \note for the client
+ * In this case, the client can waiting files forever.
+ * So the client must has to wait only a few seconds.
+ * If the client could not get the any data in that time,
+ * it should cancel the waiting.
+ */
+ }
+ }
+
+ break;
+ case PACKET_REQ_NOACK:
+ case PACKET_ACK:
+ /* File service has no this case, it is passive service type */
+ ErrPrint("Invalid packet.\n");
+ break;
+ default:
+ break;
+ }
+
+ return LB_STATUS_SUCCESS;
+}
+
+static int send_file(int handle, const struct request_item *item)
+{
+ struct burst_head *head;
+ struct burst_data *body;
+ int pktsz;
+ int flen;
+ off_t fsize;
+ int fd;
+ int ret = 0;
+
+ /* TODO: push a file to the client */
+ fd = open(item->data.filename, O_RDONLY);
+ if (fd < 0) {
+ ErrPrint("open: %s\n", strerror(errno));
+ return -EIO;
+ }
+
+ flen = strlen(item->data.filename);
+ if (flen == 0) {
+ ret = -EINVAL;
+ goto errout;
+ }
+
+ pktsz = sizeof(*head) + flen + 1;
+
+ head = malloc(pktsz);
+ if (!head) {
+ ErrPrint("heap: %s\n", strerror(errno));
+ ret = -ENOMEM;
+ goto errout;
+ }
+
+ fsize = lseek(fd, 0L, SEEK_END);
+ if (fsize == (off_t)-1) {
+ ErrPrint("heap: %s\n", strerror(errno));
+ free(head);
+ ret = -EIO;
+ goto errout;
+ }
+
+ head->flen = flen;
+ head->size = fsize;
+ strcpy(head->fname, item->data.filename);
+
+ /* Anytime we can fail to send packet */
+ ret = com_core_send(handle, (void *)head, pktsz, 2.0f);
+ free(head);
+ if (ret < 0) {
+ ret = -EFAULT;
+ goto errout;
+ }
+
+ if (lseek(fd, 0L, SEEK_SET) == (off_t)-1) {
+ ErrPrint("seek: %s\n", strerror(errno));
+
+ body = malloc(sizeof(*body));
+ if (!body) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ return -ENOMEM;
+ }
+
+ body->size = -1;
+ ret = com_core_send(handle, (void *)body, sizeof(*body), 2.0f);
+ free(body);
+
+ if (ret < 0)
+ ret = -EFAULT;
+ else
+ ret = -EIO;
+
+ goto errout;
+ }
+
+ body = malloc(PKT_CHUNKSZ + sizeof(*body));
+ if (!body) {
+ ErrPrint("heap: %s\n", strerror(errno));
+ goto errout;
+ }
+
+ /* Burst pushing. */
+ while (fsize > 0) {
+ if (fsize > PKT_CHUNKSZ) {
+ body->size = PKT_CHUNKSZ;
+ fsize -= PKT_CHUNKSZ;
+ } else {
+ body->size = fsize;
+ fsize = 0;
+ }
+
+ pktsz = sizeof(*body) + body->size;
+
+ ret = read(fd, body->data, body->size);
+ if (ret < 0) {
+ ErrPrint("read: %s\n", strerror(errno));
+ ret = -EIO;
+ break;
+ }
+
+ /* Send BODY */
+ ret = com_core_send(handle, (void *)body, pktsz, 2.0f);
+ if (ret != pktsz) {
+ ret = -EFAULT;
+ break;
+ }
+ }
+
+ /* Send EOF */
+ body->size = -1;
+ ret = com_core_send(handle, (void *)body, sizeof(*body), 2.0f);
+ if (ret < 0)
+ ret = -EFAULT;
+
+ free(body);
+
+errout:
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
+
+ return ret;
+}
+
+static int send_buffer(int handle, const struct request_item *item)
+{
+ struct buffer *buffer;
+ struct burst_head *head;
+ struct burst_data *body;
+ char *data;
+ int pktsz;
+ int ret;
+ int size;
+ int offset;
+ int type;
+
+ if (item->type == REQUEST_TYPE_SHM)
+ type = BUFFER_TYPE_SHM;
+ else
+ type = BUFFER_TYPE_PIXMAP;
+
+ buffer = buffer_handler_raw_open(type, (void *)item->data.shm);
+ if (!buffer)
+ return -EINVAL;
+
+ pktsz = sizeof(*head);
+
+ head = malloc(pktsz);
+ if (!head) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ (void)buffer_handler_raw_close(buffer);
+ return -ENOMEM;
+ }
+
+ size = head->size = buffer_handler_raw_size(buffer);
+ head->flen = 0;
+
+ /* Anytime we can fail to send packet */
+ ret = com_core_send(handle, (void *)head, pktsz, 2.0f);
+ free(head);
+ if (ret < 0) {
+ ret = -EFAULT;
+ goto errout;
+ }
+
+ body = malloc(sizeof(*body) + PKT_CHUNKSZ);
+ if (!body) {
+ ret = -ENOMEM;
+ goto errout;
+ }
+
+ data = (char *)buffer_handler_raw_data(buffer);
+ offset = 0;
+ while (offset < size) {
+ body->size = size - offset;
+
+ if (body->size > PKT_CHUNKSZ)
+ body->size = PKT_CHUNKSZ;
+
+ memcpy(body->data, data, body->size);
+ pktsz = sizeof(*body) + body->size;
+
+ ret = com_core_send(handle, (void *)body, pktsz, 2.0f);
+ if (ret < 0) {
+ ret = -EFAULT;
+ break;
+ }
+
+ offset += body->size;
+ }
+
+ free(body);
+
+errout:
+ (void)buffer_handler_raw_close(buffer);
+ return ret;
+}
+
+static void *push_main(void *data)
+{
+ fd_set set;
+ int ret;
+ char ch;
+ struct request_item *item;
+ int conn_fd;
+ send_data_func_t send_data[] = {
+ send_file,
+ send_buffer,
+ send_buffer,
+ };
+
+ while (1) {
+ FD_ZERO(&set);
+ FD_SET(s_info.request_pipe[PIPE_READ], &set);
+
+ ret = select(s_info.request_pipe[PIPE_READ] + 1, &set, NULL, NULL, NULL);
+ if (ret < 0) {
+ ret = -errno;
+ if (errno == EINTR) {
+ ErrPrint("INTERRUPTED\n");
+ ret = 0;
+ continue;
+ }
+ ErrPrint("Error: %s\n", strerror(errno));
+ break;
+ } else if (ret == 0) {
+ ErrPrint("Timeout\n");
+ ret = -ETIMEDOUT;
+ break;
+ }
+
+ if (!FD_ISSET(s_info.request_pipe[PIPE_READ], &set)) {
+ DbgPrint("Unknown data\n");
+ ret = -EINVAL;
+ break;
+ }
+
+ ret = read(s_info.request_pipe[PIPE_READ], &ch, sizeof(ch));
+ if (ret != sizeof(ch)) {
+ ErrPrint("read: %s\n", strerror(errno));
+ ret = -EFAULT;
+ break;
+ }
+
+ if (ch == PUSH_EXIT) {
+ DbgPrint("Thread is terminating\n");
+ ret = -ECANCELED;
+ break;
+ }
+
+ CRITICAL_SECTION_BEGIN(&s_info.request_list_lock);
+ item = eina_list_nth(s_info.request_list, 0);
+ s_info.request_list = eina_list_remove(s_info.request_list, item);
+ CRITICAL_SECTION_END(&s_info.request_list_lock);
+
+ if (!item) {
+ ErrPrint("Request item is not valid\n");
+ continue;
+ }
+
+ /* Validate the TCB? */
+ conn_fd = tcb_is_valid(s_info.svc_ctx, item->tcb);
+ if (conn_fd < 0) {
+ ErrPrint("TCB is not valid\n");
+ destroy_request_item(item);
+ continue;
+ }
+
+ /*
+ * \note
+ * From now, we cannot believe the conn_fd.
+ * It can be closed any time.
+ * Even though we using it.
+ */
+ if (item->type < REQUEST_TYPE_MAX && item->type >= 0)
+ (void)send_data[item->type](conn_fd, item);
+ else
+ ErrPrint("Invalid type\n");
+
+ destroy_request_item(item);
+ }
+
+ return (void *)ret;
+}
+
+/* MAIN THREAD */
+int file_service_init(void)
+{
+ int status;
+
+ if (s_info.svc_ctx) {
+ ErrPrint("Already initialized\n");
+ return LB_STATUS_ERROR_ALREADY;
+ }
+
+ if (pipe2(s_info.request_pipe, O_NONBLOCK | O_CLOEXEC) < 0) {
+ ErrPrint("pipe: %s\n", strerror(errno));
+ return LB_STATUS_ERROR_FAULT;
+ }
+
+ status = pthread_mutex_init(&s_info.request_list_lock, NULL);
+ if (status != 0) {
+ ErrPrint("Failed to create lock: %s\n", strerror(status));
+ CLOSE_PIPE(s_info.request_pipe);
+ return LB_STATUS_ERROR_FAULT;
+ }
+
+ s_info.svc_ctx = service_common_create(FILE_SERVICE_ADDR, service_thread_main, NULL);
+ if (!s_info.svc_ctx) {
+ ErrPrint("Unable to activate service thread\n");
+
+ status = pthread_mutex_destroy(&s_info.request_list_lock);
+ if (status != 0)
+ ErrPrint("Destroy lock: %s\n", strerror(status));
+
+ CLOSE_PIPE(s_info.request_pipe);
+ return LB_STATUS_ERROR_FAULT;
+ }
+
+ status = pthread_create(&s_info.push_thid, NULL, push_main, NULL);
+ if (status != 0) {
+ ErrPrint("Failed to create a push service: %s\n", strerror(status));
+
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+
+ status = pthread_mutex_destroy(&s_info.request_list_lock);
+ if (status != 0)
+ ErrPrint("Destroy lock: %s\n", strerror(status));
+
+ CLOSE_PIPE(s_info.request_pipe);
+ return LB_STATUS_ERROR_FAULT;
+ }
+
+ /*!
+ * \note
+ * Remote service doesn't need to set the additional SMAK label.
+ */
+
+ DbgPrint("Successfully initiated\n");
+ return LB_STATUS_SUCCESS;
+}
+
+/* MAIN THREAD */
+int file_service_fini(void)
+{
+ struct request_item *item;
+ int status;
+ char ch;
+ void *retval;
+
+ if (!s_info.svc_ctx)
+ return LB_STATUS_ERROR_INVALID;
+
+ ch = PUSH_EXIT;
+ status = write(s_info.request_pipe[PIPE_WRITE], &ch, sizeof(ch));
+ if (status != sizeof(ch)) {
+ ErrPrint("write: %s\n", strerror(errno));
+ /* Forcely terminate the thread */
+ status = pthread_cancel(s_info.push_thid);
+ if (status != 0)
+ ErrPrint("cancel: %s\n", strerror(status));
+ }
+
+ status = pthread_join(s_info.push_thid, &retval);
+ if (status != 0)
+ ErrPrint("join: %s\n", strerror(status));
+
+ CRITICAL_SECTION_BEGIN(&s_info.request_list_lock);
+ EINA_LIST_FREE(s_info.request_list, item) {
+ destroy_request_item(item);
+ }
+ CRITICAL_SECTION_END(&s_info.request_list_lock);
+
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+
+ status = pthread_mutex_destroy(&s_info.request_list_lock);
+ if (status != 0)
+ ErrPrint("destroy mutex: %s\n", strerror(status));
+
+ CLOSE_PIPE(s_info.request_pipe);
+
+ DbgPrint("Successfully Finalized\n");
+ return LB_STATUS_SUCCESS;
+}
+
+/* End of a file */
diff --git a/src/main.c b/src/main.c
index b8441bf..b806925 100644
--- a/src/main.c
+++ b/src/main.c
@@ -56,6 +56,7 @@
#include "notification_service.h"
#include "utility_service.h"
#include "badge_service.h"
+#include "file_service.h"
#if defined(FLOG)
FILE *__file_log_fp;
@@ -125,6 +126,8 @@ static inline int app_create(void)
utility_service_init();
script_init();
+ file_service_init();
+
return 0;
}
@@ -132,6 +135,9 @@ static inline int app_terminate(void)
{
int ret;
+ ret = file_service_fini();
+ DbgPrint("Finalize the file service: %d\n", ret);
+
ret = server_fini();
DbgPrint("Finalize server: %d\n", ret);
diff --git a/src/server.c b/src/server.c
index f8404fd..365d06b 100644
--- a/src/server.c
+++ b/src/server.c
@@ -57,11 +57,13 @@ static struct info {
int client_fd;
int service_fd;
int slave_fd;
+ int remote_client_fd;
} s_info = {
.info_fd = -1,
.client_fd = -1,
.service_fd = -1,
.slave_fd = -1,
+ .remote_client_fd = -1,
};
/* Share this with provider */
@@ -460,7 +462,7 @@ static struct packet *client_acquire(pid_t pid, int handle, const struct packet
double timestamp;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (client) {
ErrPrint("Client is already exists %d\n", pid);
ret = LB_STATUS_ERROR_EXIST;
@@ -498,7 +500,7 @@ static struct packet *cilent_release(pid_t pid, int handle, const struct packet
struct packet *result;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -560,7 +562,7 @@ static struct packet *client_clicked(pid_t pid, int handle, const struct packet
int ret;
struct inst_info *inst;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
goto out;
@@ -596,7 +598,7 @@ static struct packet *client_update_mode(pid_t pid, int handle, const struct pac
int ret;
struct inst_info *inst;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_INVALID;
@@ -643,7 +645,7 @@ static struct packet *client_text_signal(pid_t pid, int handle, const struct pac
struct inst_info *inst;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -702,7 +704,7 @@ static struct packet *client_delete(pid_t pid, int handle, const struct packet *
struct inst_info *inst;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -783,7 +785,7 @@ static struct packet *client_resize(pid_t pid, int handle, const struct packet *
struct inst_info *inst;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -838,7 +840,7 @@ static struct packet *client_new(pid_t pid, int handle, const struct packet *pac
char *lb_pkgname;
char *mainappid;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -915,7 +917,7 @@ static struct packet *client_change_visibility(pid_t pid, int handle, const stru
int ret;
struct inst_info *inst;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -958,7 +960,7 @@ static struct packet *client_set_period(pid_t pid, int handle, const struct pack
int ret;
struct inst_info *inst;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1007,7 +1009,7 @@ static struct packet *client_change_group(pid_t pid, int handle, const struct pa
struct inst_info *inst;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1057,7 +1059,7 @@ static struct packet *client_pd_mouse_enter(pid_t pid, int handle, const struct
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1118,7 +1120,7 @@ static struct packet *client_pd_mouse_leave(pid_t pid, int handle, const struct
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1179,7 +1181,7 @@ static struct packet *client_pd_mouse_down(pid_t pid, int handle, const struct p
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1240,7 +1242,7 @@ static struct packet *client_pd_mouse_up(pid_t pid, int handle, const struct pac
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1301,7 +1303,7 @@ static struct packet *client_pd_mouse_move(pid_t pid, int handle, const struct p
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1362,7 +1364,7 @@ static struct packet *client_lb_mouse_move(pid_t pid, int handle, const struct p
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1429,7 +1431,7 @@ static struct packet *client_lb_mouse_set(pid_t pid, int handle, const struct pa
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1485,7 +1487,7 @@ static struct packet *client_lb_mouse_unset(pid_t pid, int handle, const struct
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1531,7 +1533,7 @@ static struct packet *client_pd_mouse_set(pid_t pid, int handle, const struct pa
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1588,7 +1590,7 @@ static struct packet *client_pd_mouse_unset(pid_t pid, int handle, const struct
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1634,7 +1636,7 @@ static struct packet *client_lb_mouse_enter(pid_t pid, int handle, const struct
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1695,7 +1697,7 @@ static struct packet *client_lb_mouse_leave(pid_t pid, int handle, const struct
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1756,7 +1758,7 @@ static struct packet *client_lb_mouse_down(pid_t pid, int handle, const struct p
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1817,7 +1819,7 @@ static struct packet *client_lb_mouse_up(pid_t pid, int handle, const struct pac
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1879,7 +1881,7 @@ static struct packet *client_pd_access_action_up(pid_t pid, int handle, const st
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -1962,7 +1964,7 @@ static struct packet *client_pd_access_action_down(pid_t pid, int handle, const
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2045,7 +2047,7 @@ static struct packet *client_pd_access_scroll_down(pid_t pid, int handle, const
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2128,7 +2130,7 @@ static struct packet *client_pd_access_scroll_move(pid_t pid, int handle, const
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2211,7 +2213,7 @@ static struct packet *client_pd_access_scroll_up(pid_t pid, int handle, const st
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2294,7 +2296,7 @@ static struct packet *client_pd_access_unhighlight(pid_t pid, int handle, const
int ret;
double timestamp;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2376,7 +2378,7 @@ static struct packet *client_pd_access_hl(pid_t pid, int handle, const struct pa
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2459,7 +2461,7 @@ static struct packet *client_pd_access_hl_prev(pid_t pid, int handle, const stru
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2542,7 +2544,7 @@ static struct packet *client_pd_access_hl_next(pid_t pid, int handle, const stru
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2631,7 +2633,7 @@ static struct packet *client_pd_access_activate(pid_t pid, int handle, const str
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2713,7 +2715,7 @@ static struct packet *client_pd_key_down(pid_t pid, int handle, const struct pac
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2770,7 +2772,7 @@ static struct packet *client_pause_request(pid_t pid, int handle, const struct p
double timestamp;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is paused - manually reported\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2799,7 +2801,7 @@ static struct packet *client_resume_request(pid_t pid, int handle, const struct
double timestamp;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
goto out;
@@ -2832,7 +2834,7 @@ static struct packet *client_pd_key_up(pid_t pid, int handle, const struct packe
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2896,7 +2898,7 @@ static struct packet *client_lb_access_hl(pid_t pid, int handle, const struct pa
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -2979,7 +2981,7 @@ static struct packet *client_lb_access_hl_prev(pid_t pid, int handle, const stru
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3062,7 +3064,7 @@ static struct packet *client_lb_access_hl_next(pid_t pid, int handle, const stru
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3145,7 +3147,7 @@ static struct packet *client_lb_access_action_up(pid_t pid, int handle, const st
int x;
int y;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exist\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3235,7 +3237,7 @@ static struct packet *client_lb_access_action_down(pid_t pid, int handle, const
int x;
int y;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exist\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3325,7 +3327,7 @@ static struct packet *client_lb_access_unhighlight(pid_t pid, int handle, const
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3408,7 +3410,7 @@ static struct packet *client_lb_access_scroll_down(pid_t pid, int handle, const
int x;
int y;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exist\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3498,7 +3500,7 @@ static struct packet *client_lb_access_scroll_move(pid_t pid, int handle, const
int x;
int y;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exist\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3588,7 +3590,7 @@ static struct packet *client_lb_access_scroll_up(pid_t pid, int handle, const st
int x;
int y;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exist\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3678,7 +3680,7 @@ static struct packet *client_lb_access_activate(pid_t pid, int handle, const str
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3762,7 +3764,7 @@ static struct packet *client_lb_key_down(pid_t pid, int handle, const struct pac
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3826,7 +3828,7 @@ static struct packet *client_lb_key_up(pid_t pid, int handle, const struct packe
struct inst_info *inst;
const struct pkg_info *pkg;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -3897,7 +3899,7 @@ static struct packet *client_lb_acquire_pixmap(pid_t pid, int handle, const stru
void *buf_ptr;
struct buffer_info *buffer;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
goto out;
@@ -3969,7 +3971,7 @@ static struct packet *client_lb_release_pixmap(pid_t pid, int handle, const stru
void *buf_ptr;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
goto out;
@@ -4011,7 +4013,7 @@ static struct packet *client_pd_acquire_pixmap(pid_t pid, int handle, const stru
void *buf_ptr;
struct buffer_info *buffer;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
goto out;
@@ -4079,7 +4081,7 @@ static struct packet *client_pd_release_pixmap(pid_t pid, int handle, const stru
void *buf_ptr;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
goto out;
@@ -4119,7 +4121,7 @@ static struct packet *client_pinup_changed(pid_t pid, int handle, const struct p
int ret;
struct inst_info *inst;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -4221,7 +4223,7 @@ static struct packet *client_pd_move(pid_t pid, int handle, const struct packet
double y = 0.0f;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -4342,7 +4344,7 @@ static struct packet *client_create_pd(pid_t pid, int handle, const struct packe
DbgPrint("PERF_DBOX\n");
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -4556,7 +4558,7 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
DbgPrint("PERF_DBOX\n");
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -4742,7 +4744,7 @@ static struct packet *client_activate_package(pid_t pid, int handle, const struc
int ret;
struct pkg_info *info;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -4792,7 +4794,7 @@ static struct packet *client_subscribed(pid_t pid, int handle, const struct pack
struct client_node *client;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -4832,7 +4834,7 @@ static struct packet *client_delete_cluster(pid_t pid, int handle, const struct
struct packet *result;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -4911,7 +4913,7 @@ static struct packet *client_update(pid_t pid, int handle, const struct packet *
const char *id;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Cilent %d is not exists\n", pid);
goto out;
@@ -4951,7 +4953,7 @@ static struct packet *client_refresh_group(pid_t pid, int handle, const struct p
Eina_List *info_list;
Eina_List *l;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Cilent %d is not exists\n", pid);
goto out;
@@ -5000,7 +5002,7 @@ static struct packet *client_delete_category(pid_t pid, int handle, const struct
struct packet *result;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -5040,7 +5042,7 @@ static struct packet *client_unsubscribed(pid_t pid, int handle, const struct pa
struct client_node *client;
int ret;
- client = client_find_by_pid(pid);
+ client = client_find_by_rpc_handle(handle);
if (!client) {
ErrPrint("Client %d is not exists\n", pid);
ret = LB_STATUS_ERROR_NOT_EXIST;
@@ -6892,6 +6894,15 @@ HAPI int server_init(void)
if (s_info.client_fd < 0)
ErrPrint("Failed to create a client socket\n");
+ /*!
+ * \note
+ * remote://:8208
+ * Skip address to use the NULL.
+ */
+ s_info.remote_client_fd = com_core_packet_server_init("remote://:"CLIENT_PORT, s_client_table);
+ if (s_info.client_fd < 0)
+ ErrPrint("Failed to create a remote client socket\n");
+
s_info.service_fd = com_core_packet_server_init(SERVICE_SOCKET, s_service_table);
if (s_info.service_fd < 0)
ErrPrint("Faild to create a service socket\n");
@@ -6928,6 +6939,11 @@ HAPI int server_fini(void)
s_info.client_fd = -1;
}
+ if (s_info.remote_client_fd > 0) {
+ com_core_packet_server_fini(s_info.remote_client_fd);
+ s_info.remote_client_fd = -1;
+ }
+
if (s_info.service_fd > 0) {
com_core_packet_server_fini(s_info.service_fd);
s_info.service_fd = -1;
diff --git a/src/service_common.c b/src/service_common.c
index d240bed..ea62e33 100644
--- a/src/service_common.c
+++ b/src/service_common.c
@@ -64,6 +64,7 @@ struct service_context {
int fd; /*!< Server socket handle */
Eina_List *tcb_list; /*!< TCB list, list of every thread for client connections */
+ pthread_mutex_t tcb_list_lock;
Eina_List *packet_list;
pthread_mutex_t packet_list_lock;
@@ -357,7 +358,9 @@ static inline struct tcb *tcb_create(struct service_context *svc_ctx, int fd)
return NULL;
}
+ CRITICAL_SECTION_BEGIN(&svc_ctx->tcb_list_lock);
svc_ctx->tcb_list = eina_list_append(svc_ctx->tcb_list, tcb);
+ CRITICAL_SECTION_END(&svc_ctx->tcb_list_lock);
return tcb;
}
@@ -407,7 +410,9 @@ static inline void tcb_destroy(struct service_context *svc_ctx, struct tcb *tcb)
int status;
char ch = EVT_END_CH;
+ CRITICAL_SECTION_BEGIN(&svc_ctx->tcb_list_lock);
svc_ctx->tcb_list = eina_list_remove(svc_ctx->tcb_list, tcb);
+ CRITICAL_SECTION_END(&svc_ctx->tcb_list_lock);
/*!
* ASSERT(tcb->fd >= 0);
* Close the connection, and then collecting the return value of thread
@@ -555,32 +560,6 @@ static void *server_main(void *data)
}
}
- if (FD_ISSET(svc_ctx->tcb_pipe[PIPE_READ], &set)) {
- if (read(svc_ctx->tcb_pipe[PIPE_READ], &tcb, sizeof(tcb)) != sizeof(tcb)) {
- ErrPrint("Unable to read pipe: %s\n", strerror(errno));
- ret = -EFAULT;
- break;
- }
-
- if (!tcb) {
- ErrPrint("Terminate service thread\n");
- ret = -ECANCELED;
- break;
- }
-
- /*!
- * \note
- * Invoke the service thread main, to notify the termination of a TCB
- */
- ret = svc_ctx->service_thread_main(tcb, NULL, svc_ctx->service_thread_data);
-
- /*!
- * at this time, the client thread can access this tcb.
- * how can I protect this TCB from deletion without disturbing the server thread?
- */
- tcb_destroy(svc_ctx, tcb);
- }
-
if (FD_ISSET(svc_ctx->evt_pipe[PIPE_READ], &set)) {
if (read(svc_ctx->evt_pipe[PIPE_READ], &evt_ch, sizeof(evt_ch)) != sizeof(evt_ch)) {
ErrPrint("Unable to read pipe: %s\n", strerror(errno));
@@ -612,6 +591,62 @@ static void *server_main(void *data)
}
processing_timer_event(svc_ctx, &set);
+
+ /*!
+ * \note
+ * Destroying TCB should be processed at last.
+ */
+ if (FD_ISSET(svc_ctx->tcb_pipe[PIPE_READ], &set)) {
+ Eina_List *lockfree_packet_list;
+ Eina_List *l;
+ Eina_List *n;
+
+ if (read(svc_ctx->tcb_pipe[PIPE_READ], &tcb, sizeof(tcb)) != sizeof(tcb)) {
+ ErrPrint("Unable to read pipe: %s\n", strerror(errno));
+ ret = -EFAULT;
+ break;
+ }
+
+ if (!tcb) {
+ ErrPrint("Terminate service thread\n");
+ ret = -ECANCELED;
+ break;
+ }
+
+ lockfree_packet_list = NULL;
+ CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
+ EINA_LIST_FOREACH_SAFE(svc_ctx->packet_list, l, n, packet_info) {
+ if (packet_info->tcb != tcb)
+ continue;
+
+ svc_ctx->packet_list = eina_list_remove(svc_ctx->packet_list, packet_info);
+ lockfree_packet_list = eina_list_append(lockfree_packet_list, packet_info);
+ }
+ CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
+
+ EINA_LIST_FREE(lockfree_packet_list, packet_info) {
+ ret = read(svc_ctx->evt_pipe[PIPE_READ], &evt_ch, sizeof(evt_ch));
+ DbgPrint("Flushing filtered pipe: %d (%c)\n", ret, evt_ch);
+ ret = svc_ctx->service_thread_main(packet_info->tcb, packet_info->packet, svc_ctx->service_thread_data);
+ if (ret < 0)
+ ErrPrint("Service thread returns: %d\n", ret);
+ packet_destroy(packet_info->packet);
+ free(packet_info);
+ }
+
+ /*!
+ * \note
+ * Invoke the service thread main, to notify the termination of a TCB
+ */
+ ret = svc_ctx->service_thread_main(tcb, NULL, svc_ctx->service_thread_data);
+
+ /*!
+ * at this time, the client thread can access this tcb.
+ * how can I protect this TCB from deletion without disturbing the server thread?
+ */
+ tcb_destroy(svc_ctx, tcb);
+ }
+
/* If there is no such triggered FD? */
}
@@ -767,6 +802,28 @@ HAPI int service_common_destroy(struct service_context *svc_ctx)
/*!
* \note
+ * SERVER THREAD or OTHER THREAD (not main)
+ */
+HAPI int tcb_is_valid(struct service_context *svc_ctx, struct tcb *tcb)
+{
+ Eina_List *l;
+ struct tcb *tmp;
+ int ret = 0;
+
+ CRITICAL_SECTION_BEGIN(&svc_ctx->tcb_list_lock);
+ EINA_LIST_FOREACH(svc_ctx->tcb_list, l, tmp) {
+ if (tmp == tcb /* && tcb->svc_ctx == svc_ctx */) {
+ ret = tcb->fd;
+ break;
+ }
+ }
+ CRITICAL_SECTION_END(&svc_ctx->tcb_list_lock);
+
+ return ret;
+}
+
+/*!
+ * \note
* SERVER THREAD
*/
HAPI int tcb_fd(struct tcb *tcb)
@@ -849,6 +906,11 @@ HAPI int service_common_multicast_packet(struct tcb *tcb, struct packet *packet,
svc_ctx = tcb->svc_ctx;
DbgPrint("Multicasting packets\n");
+
+ /*!
+ * \note
+ * Does not need to make a critical section from here.
+ */
EINA_LIST_FOREACH(svc_ctx->tcb_list, l, target) {
if (target == tcb || target->type != type) {
DbgPrint("Skip target: %p(%d) == %p/%d\n", target, target->type, tcb, type);
diff --git a/src/shortcut_service.c b/src/shortcut_service.c
index 82408a3..edebb38 100644
--- a/src/shortcut_service.c
+++ b/src/shortcut_service.c
@@ -171,6 +171,11 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat
break;
}
+ if (tcb_is_valid(s_info.svc_ctx, tcb) < 0) {
+ ErrPrint("TCB is not valid (already disconnected?)\n");
+ break;
+ }
+
if (service_common_unicast_packet(tcb, packet) < 0)
ErrPrint("Unable to send reply packet\n");
break;
diff --git a/src/slave_life.c b/src/slave_life.c
index 8d36a27..335b193 100644
--- a/src/slave_life.c
+++ b/src/slave_life.c
@@ -77,6 +77,8 @@ struct slave_node {
Ecore_Timer *ttl_timer; /* Time to live */
Ecore_Timer *activate_timer; /* Waiting hello packet for this time */
+ Ecore_Timer *relaunch_timer; /* Try to relaunch service app */
+ int relaunch_count;
struct timeval activated_at;
};
@@ -170,6 +172,7 @@ static inline struct slave_node *create_slave_node(const char *name, int is_secu
slave->pid = (pid_t)-1;
slave->state = SLAVE_TERMINATED;
slave->network = network;
+ slave->relaunch_count = SLAVE_RELAUNCH_COUNT;
xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_pause_cb, slave);
xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resume_cb, slave);
@@ -241,6 +244,9 @@ static inline void destroy_slave_node(struct slave_node *slave)
if (slave->activate_timer)
ecore_timer_del(slave->activate_timer);
+ if (slave->relaunch_timer)
+ ecore_timer_del(slave->relaunch_timer);
+
DbgFree(slave->abi);
DbgFree(slave->name);
DbgFree(slave->pkgname);
@@ -376,6 +382,11 @@ static Eina_Bool activate_timer_cb(void *data)
{
struct slave_node *slave = data;
+ if (slave->relaunch_timer) {
+ ecore_timer_del(slave->relaunch_timer);
+ slave->relaunch_timer = NULL;
+ }
+
slave->fault_count++;
invoke_fault_cb(slave);
@@ -396,6 +407,106 @@ static Eina_Bool activate_timer_cb(void *data)
return ECORE_CALLBACK_CANCEL;
}
+static inline void invoke_slave_fault_handler(struct slave_node *slave)
+{
+ slave->fault_count++;
+ invoke_fault_cb(slave);
+
+ slave_set_reactivation(slave, 0);
+ slave_set_reactivate_instances(slave, 0);
+
+ if (slave_pid(slave) > 0) {
+ int ret;
+ DbgPrint("Try to terminate PID: %d\n", slave_pid(slave));
+ ret = aul_terminate_pid(slave_pid(slave));
+ if (ret < 0)
+ ErrPrint("Terminate failed, pid %d (reason: %d)\n", slave_pid(slave), ret);
+ }
+}
+
+static Eina_Bool relaunch_timer_cb(void *data)
+{
+ struct slave_node *slave = data;
+ int ret = ECORE_CALLBACK_CANCEL;
+
+ if (!slave->activate_timer) {
+ ErrPrint("Activate timer is not valid\n");
+ slave->relaunch_timer = NULL;
+
+ invoke_slave_fault_handler(slave);
+ } else if (!slave->relaunch_count) {
+ ErrPrint("Relaunch count is exhahausted\n");
+ ecore_timer_del(slave->activate_timer);
+ slave->activate_timer = NULL;
+
+ slave->relaunch_timer = NULL;
+ invoke_slave_fault_handler(slave);
+ } else {
+ bundle *param;
+
+ param = bundle_create();
+ if (!param) {
+ ErrPrint("Failed to create a bundle\n");
+
+ ecore_timer_del(slave->activate_timer);
+ slave->activate_timer = NULL;
+
+ slave->relaunch_timer = NULL;
+
+ invoke_slave_fault_handler(slave);
+ } else {
+ bundle_add(param, BUNDLE_SLAVE_NAME, slave_name(slave));
+ bundle_add(param, BUNDLE_SLAVE_SECURED, slave->secured ? "true" : "false");
+ bundle_add(param, BUNDLE_SLAVE_ABI, slave->abi);
+
+ slave->pid = (pid_t)aul_launch_app(slave_pkgname(slave), param);
+
+ bundle_free(param);
+
+ switch (slave->pid) {
+ case AUL_R_ENOLAUNCHPAD: /**< no launchpad */
+ case AUL_R_EILLACC: /**< Illegal Access */
+ case AUL_R_LOCAL: /**< Launch by himself */
+ case AUL_R_ETIMEOUT: /**< Timeout */
+ case AUL_R_EINVAL: /**< Invalid argument */
+ case AUL_R_OK: /**< General success */
+ case AUL_R_ENOINIT: /**< AUL handler NOT initialized */
+ case AUL_R_ERROR: /**< General error */
+ CRITICAL_LOG("Failed to launch a new slave %s (%d)\n", slave_name(slave), slave->pid);
+ slave->pid = (pid_t)-1;
+ ecore_timer_del(slave->activate_timer);
+ slave->activate_timer = NULL;
+
+ slave->relaunch_timer = NULL;
+
+ invoke_slave_fault_handler(slave);
+ /* Waiting app-launch result */
+ break;
+ case AUL_R_ECOMM: /**< Comunication Error */
+ case AUL_R_ETERMINATING: /**< application terminating */
+ case AUL_R_ECANCELED: /**< Operation canceled */
+ slave->relaunch_count--;
+
+ CRITICAL_LOG("Try relaunch again %s (%d), %d\n", slave_name(slave), slave->pid, slave->relaunch_count);
+ slave->pid = (pid_t)-1;
+ ret = ECORE_CALLBACK_RENEW;
+ ecore_timer_reset(slave->activate_timer);
+ /* Try again after a few secs later */
+ break;
+ default:
+ DbgPrint("Slave %s is launched with %d as %s\n", slave_pkgname(slave), slave->pid, slave_name(slave));
+ slave->relaunch_timer = NULL;
+ ecore_timer_reset(slave->activate_timer);
+ break;
+ }
+ }
+
+ }
+
+ return ret;
+}
+
+
HAPI int slave_activate(struct slave_node *slave)
{
/*!
@@ -421,6 +532,8 @@ HAPI int slave_activate(struct slave_node *slave)
} else {
bundle *param;
+ slave->relaunch_count = SLAVE_RELAUNCH_COUNT;
+
param = bundle_create();
if (!param) {
ErrPrint("Failed to create a bundle\n");
@@ -435,18 +548,35 @@ HAPI int slave_activate(struct slave_node *slave)
bundle_free(param);
- if (slave->pid < 0) {
+ switch (slave->pid) {
+ case AUL_R_ENOLAUNCHPAD: /**< no launchpad */
+ case AUL_R_EILLACC: /**< Illegal Access */
+ case AUL_R_LOCAL: /**< Launch by himself */
+ case AUL_R_ETIMEOUT: /**< Timeout */
+ case AUL_R_EINVAL: /**< Invalid argument */
+ case AUL_R_OK: /**< General success */
+ case AUL_R_ENOINIT: /**< AUL handler NOT initialized */
+ case AUL_R_ERROR: /**< General error */
CRITICAL_LOG("Failed to launch a new slave %s (%d)\n", slave_name(slave), slave->pid);
- if (slave->pid != AUL_R_ETIMEOUT && slave->pid != AUL_R_ECOMM) {
- ErrPrint("failed, because of %d\n", slave->pid);
+ slave->pid = (pid_t)-1;
+ /* Waiting app-launch result */
+ break;
+ case AUL_R_ECOMM: /**< Comunication Error */
+ case AUL_R_ETERMINATING: /**< application terminating */
+ case AUL_R_ECANCELED: /**< Operation canceled */
+ CRITICAL_LOG("Try relaunch this soon %s (%d)\n", slave_name(slave), slave->pid);
+ slave->relaunch_timer = ecore_timer_add(SLAVE_RELAUNCH_TIME, relaunch_timer_cb, slave);
+ if (!slave->relaunch_timer) {
+ CRITICAL_LOG("Failed to register a relaunch timer (%s)\n", slave_name(slave));
slave->pid = (pid_t)-1;
return LB_STATUS_ERROR_FAULT;
- } else {
- ErrPrint("But waiting \"hello\"\n");
- slave->pid = (pid_t)-1;
}
+ /* Try again after a few secs later */
+ break;
+ default:
+ DbgPrint("Slave %s is launched with %d as %s\n", slave_pkgname(slave), slave->pid, slave_name(slave));
+ break;
}
- DbgPrint("Slave %s is launched with %d as %s\n", slave_pkgname(slave), slave->pid, slave_name(slave));
slave->activate_timer = ecore_timer_add(SLAVE_ACTIVATE_TIME, activate_timer_cb, slave);
if (!slave->activate_timer)
@@ -529,6 +659,11 @@ HAPI int slave_activated(struct slave_node *slave)
slave->activate_timer = NULL;
}
+ if (slave->relaunch_timer) {
+ ecore_timer_del(slave->relaunch_timer);
+ slave->relaunch_timer = NULL;
+ }
+
return LB_STATUS_SUCCESS;
}
@@ -607,6 +742,11 @@ HAPI struct slave_node *slave_deactivated(struct slave_node *slave)
slave->activate_timer = NULL;
}
+ if (slave->relaunch_timer) {
+ ecore_timer_del(slave->relaunch_timer);
+ slave->relaunch_timer = NULL;
+ }
+
reactivate = invoke_deactivate_cb(slave);
slave = slave_unref(slave);
diff --git a/src/utility_service.c b/src/utility_service.c
index 0b01608..723d22a 100644
--- a/src/utility_service.c
+++ b/src/utility_service.c
@@ -33,7 +33,7 @@
#include "conf.h"
#ifndef SVC_PKG
-#define SVC_PKG "org.tizen.data-provider-slave.icon"
+#define SVC_PKG "com.samsung.data-provider-slave.icon"
#endif
#ifndef LAUNCH_TIMEOUT
@@ -242,7 +242,7 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat
s_info.svc_daemon_is_launched = 0;
}
- return 0;
+ return LB_STATUS_SUCCESS;
}
cmd = packet_command(packet);
diff --git a/src/xmonitor.c b/src/xmonitor.c
index e8870df..e986215 100644
--- a/src/xmonitor.c
+++ b/src/xmonitor.c
@@ -164,7 +164,7 @@ HAPI int xmonitor_update_state(int target_pid)
struct client_node *client;
int pid;
- if (!USE_XMONITOR)
+ if (!USE_XMONITOR || target_pid < 0)
return LB_STATUS_SUCCESS;
win = ecore_x_window_focus_get();