But not yet published.
Slave Life cycle management code is updated.
(Return value handling codes are updated)
Change-Id: I8670b9502c11dce404b5a42db6e00fc31dbbdbe4
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})
src/notification_service.c
src/utility_service.c
src/service_common.c
+ src/file_service.c
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkg_LDFLAGS} "-ldl")
struct buffer_info;
struct inst_info;
+struct buffer;
enum buffer_type { /*!< Must have to be sync with libprovider, liblivebox-viewer */
BUFFER_TYPE_FILE,
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 */
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
double slave_ttl;
double slave_activate_time;
+ double slave_relaunch_time;
+ int slave_relaunch_count;
int max_log_line;
int max_log_file;
#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
--- /dev/null
+/*
+ * 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 */
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);
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
%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}
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"
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 */
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 */
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;
}
}
}
-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;
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;
}
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;
rpc = client_data(command->client, RPC_TAG);
if (!rpc) {
- ErrPrint("Invalid command\n");
+ ErrPrint("Client is not activated\n");
goto out;
}
.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,
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)
.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,
},
{
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);
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;
}
--- /dev/null
+/*
+ * 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 */
#include "notification_service.h"
#include "utility_service.h"
#include "badge_service.h"
+#include "file_service.h"
#if defined(FLOG)
FILE *__file_log_fp;
utility_service_init();
script_init();
+ file_service_init();
+
return 0;
}
{
int ret;
+ ret = file_service_fini();
+ DbgPrint("Finalize the file service: %d\n", ret);
+
ret = server_fini();
DbgPrint("Finalize server: %d\n", ret);
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 */
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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");
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;
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;
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;
}
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
}
}
- 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));
}
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? */
}
/*!
* \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)
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);
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;
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;
};
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);
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);
{
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);
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)
{
/*!
} else {
bundle *param;
+ slave->relaunch_count = SLAVE_RELAUNCH_COUNT;
+
param = bundle_create();
if (!param) {
ErrPrint("Failed to create a bundle\n");
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)
slave->activate_timer = NULL;
}
+ if (slave->relaunch_timer) {
+ ecore_timer_del(slave->relaunch_timer);
+ slave->relaunch_timer = NULL;
+ }
+
return LB_STATUS_SUCCESS;
}
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);
#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
s_info.svc_daemon_is_launched = 0;
}
- return 0;
+ return LB_STATUS_SUCCESS;
}
cmd = packet_command(packet);
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();