#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
#define LAUNCH_TIMEOUT 10.0f
#endif
+#ifndef TTL_TIMEOUT
+#define TTL_TIMEOUT 30.0f
+#endif
+
static struct info {
Eina_List *pending_list;
Eina_List *context_list;
struct tcb *svc_daemon;
int svc_daemon_is_launched;
+ int svc_daemon_pid;
struct service_event_item *launch_timer;
struct service_event_item *delay_launcher;
+ struct service_event_item *ttl_timer;
} s_info = {
.pending_list = NULL,
.context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
.svc_daemon = NULL,
.svc_daemon_is_launched = 0,
+ .svc_daemon_pid = -1,
.launch_timer = NULL,
.delay_launcher = NULL,
+ .ttl_timer = NULL,
};
struct pending_item {
static int lazy_launcher_cb(struct service_context *svc_ctx, void *data);
-static inline int put_reply_tcb(struct tcb *tcb, double seq)
+static int put_reply_tcb(struct tcb *tcb, double seq)
{
struct context *ctx;
ctx->seq = seq;
s_info.context_list = eina_list_append(s_info.context_list, ctx);
+
return LB_STATUS_SUCCESS;
}
struct tcb *tcb;
EINA_LIST_FOREACH_SAFE(s_info.context_list, l, n, ctx) {
- if (ctx->seq != seq)
+ if (ctx->seq != seq) {
continue;
+ }
s_info.context_list = eina_list_remove(s_info.context_list, ctx);
tcb = ctx->tcb;
- free(ctx);
+ DbgFree(ctx);
return tcb;
}
int ret;
EINA_LIST_FREE(s_info.pending_list, item) {
- ret = service_common_unicast_packet(s_info.svc_daemon, item->packet);
+ if (tcb_is_valid(s_info.svc_ctx, s_info.svc_daemon) >= 0) {
+ ret = service_common_unicast_packet(s_info.svc_daemon, item->packet);
+ } else {
+ ret = -EFAULT;
+ }
+
if (ret < 0) {
- struct packet *reply;
- reply = packet_create_reply(item->packet, "i", ret);
- if (service_common_unicast_packet(item->tcb, reply) < 0)
- ErrPrint("Unable to send packet\n");
- packet_destroy(reply);
+ if (tcb_is_valid(s_info.svc_ctx, item->tcb) >= 0) {
+ struct packet *reply;
+ reply = packet_create_reply(item->packet, "i", ret);
+ if (service_common_unicast_packet(item->tcb, reply) < 0) {
+ ErrPrint("Unable to send packet\n");
+ }
+ packet_destroy(reply);
+ }
} else {
put_reply_tcb(item->tcb, packet_seq(item->packet));
}
packet_unref(item->packet);
- free(item);
+ DbgFree(item);
}
return 0;
item->tcb = tcb;
item->packet = packet_ref(packet);
if (!item->packet) {
- free(item);
+ DbgFree(item);
ErrPrint("Unable to ref packet\n");
return LB_STATUS_ERROR_FAULT;
}
struct packet *reply;
EINA_LIST_FREE(s_info.pending_list, item) {
- reply = packet_create_reply(item->packet, "i", -EFAULT);
- if (!reply) {
- ErrPrint("Unable to create a packet\n");
+ if (tcb_is_valid(s_info.svc_ctx, item->tcb) >= 0) {
+ reply = packet_create_reply(item->packet, "i", -EFAULT);
+ if (!reply) {
+ ErrPrint("Unable to create a packet\n");
+ } else {
+ int ret;
+
+ ret = service_common_unicast_packet(item->tcb, reply);
+ if (ret < 0) {
+ ErrPrint("Failed to send reply packet: %d\n", ret);
+ }
+
+ packet_destroy(reply);
+ }
} else {
- int ret;
-
- ret = service_common_unicast_packet(item->tcb, reply);
- if (ret < 0)
- ErrPrint("Failed to send reply packet: %d\n", ret);
-
- packet_destroy(reply);
+ ErrPrint("TCB is already terminated\n");
}
packet_unref(item->packet);
- free(item);
+ DbgFree(item);
}
s_info.launch_timer = NULL;
s_info.svc_daemon_is_launched = 0;
+ s_info.svc_daemon_pid = -1;
return -ECANCELED; /* Delete this timer */
}
-static inline int launch_svc(struct service_context *svc_ctx)
+static int launch_svc(struct service_context *svc_ctx)
{
pid_t pid;
int ret = LB_STATUS_SUCCESS;
pid = aul_launch_app(SVC_PKG, NULL);
- if (pid > 0) {
- s_info.svc_daemon_is_launched = 1;
- s_info.launch_timer = service_common_add_timer(svc_ctx, LAUNCH_TIMEOUT, launch_timeout_cb, NULL);
- if (!s_info.launch_timer)
- ErrPrint("Unable to create launch timer\n");
- } else if (pid == AUL_R_ETIMEOUT || pid == AUL_R_ECOMM) {
- s_info.svc_daemon_is_launched = 1;
- CRITICAL_LOG("SVC launch failed with timeout(%d), But waiting response\n", pid);
- s_info.launch_timer = service_common_add_timer(svc_ctx, LAUNCH_TIMEOUT, launch_timeout_cb, NULL);
- if (!s_info.launch_timer)
- ErrPrint("Unable to create launch timer\n");
- } else if (pid == AUL_R_ETERMINATING) {
+ switch (pid) {
+ //case AUL_R_EHIDDENFORGUEST: /**< App hidden for guest mode */
+ case AUL_R_ENOLAUNCHPAD: /**< no launchpad */
+ case AUL_R_EILLACC: /**< Illegal Access */
+ case AUL_R_EINVAL: /**< Invalid argument */
+ case AUL_R_ENOINIT: /**< AUL handler NOT initialized */
+ case AUL_R_ERROR: /**< General error */
+ ErrPrint("Failed to launch an app: %s(%d)\n", SVC_PKG, pid);
+ ret = LB_STATUS_ERROR_FAULT;
+ break;
+ case AUL_R_ETIMEOUT: /**< Timeout */
+ case AUL_R_ECOMM: /**< Comunication Error */
+ case AUL_R_ETERMINATING: /**< application terminating */
+ case AUL_R_ECANCELED: /**< Operation canceled */
/* Need time to launch app again */
- ErrPrint("Terminating now, try to launch this after few sec later\n");
+ ErrPrint("Terminating now, try to launch this after few sec later: %s(%d)\n", SVC_PKG, pid);
s_info.svc_daemon_is_launched = 1;
s_info.delay_launcher = service_common_add_timer(svc_ctx, LAUNCH_TIMEOUT, lazy_launcher_cb, NULL);
if (!s_info.delay_launcher) {
ErrPrint("Unable to add delay launcher\n");
ret = LB_STATUS_ERROR_FAULT;
}
- } else {
- ErrPrint("Failed to launch an app: %s(%d)\n", SVC_PKG, pid);
- ret = LB_STATUS_ERROR_FAULT;
+ break;
+ case AUL_R_LOCAL: /**< Launch by himself */
+ case AUL_R_OK: /**< General success */
+ default:
+ DbgPrint("Launched: %s(%d)\n", SVC_PKG, pid);
+ s_info.svc_daemon_is_launched = 1;
+ s_info.svc_daemon_pid = pid;
+ s_info.launch_timer = service_common_add_timer(svc_ctx, LAUNCH_TIMEOUT, launch_timeout_cb, NULL);
+ if (!s_info.launch_timer) {
+ ErrPrint("Unable to create launch timer\n");
+ }
}
return ret;
static int lazy_launcher_cb(struct service_context *svc_ctx, void *data)
{
- s_info.svc_daemon_is_launched = launch_svc(svc_ctx) == LB_STATUS_SUCCESS;
s_info.delay_launcher = NULL;
+
+ (void)launch_svc(svc_ctx);
+ return -ECANCELED;
+}
+
+static int ttl_timer_cb(struct service_context *svc_ctx, void *data)
+{
+ DbgPrint("TTL Timer is expired: PID(%d)\n", s_info.svc_daemon_pid);
+ (void)aul_terminate_pid(s_info.svc_daemon_pid);
+
+ s_info.ttl_timer = NULL;
+ s_info.svc_daemon_is_launched = 0;
+ s_info.svc_daemon_pid = -1;
+ s_info.svc_daemon = NULL;
return -ECANCELED;
}
int ret;
if (!packet) {
- DbgPrint("TCB %p is terminated (NIL packet)\n", tcb);
+ DbgPrint("TCB %p is terminated (NIL packet), %d\n", tcb, s_info.svc_daemon_pid);
if (tcb == s_info.svc_daemon) {
s_info.svc_daemon = NULL;
s_info.svc_daemon_is_launched = 0;
+ s_info.svc_daemon_pid = -1;
+
+ if (s_info.ttl_timer) {
+ service_common_del_timer(tcb_svc_ctx(tcb), s_info.ttl_timer);
+ s_info.ttl_timer = NULL;
+ }
}
- return 0;
+ return LB_STATUS_SUCCESS;
}
cmd = packet_command(packet);
case PACKET_REQ:
if (!s_info.svc_daemon_is_launched) {
ret = launch_svc(tcb_svc_ctx(tcb));
- if (ret != LB_STATUS_SUCCESS)
+ if (ret != LB_STATUS_SUCCESS) {
goto reply_out;
+ }
}
if (!s_info.svc_daemon) {
ret = put_pended_request(tcb, packet);
- if (ret < 0)
+ if (ret < 0) {
goto reply_out;
- } else {
+ }
+ } else if (tcb_is_valid(s_info.svc_ctx, s_info.svc_daemon) >= 0) {
ret = service_common_unicast_packet(s_info.svc_daemon, packet);
- if (ret <0)
+ if (ret <0) {
goto reply_out;
+ }
put_reply_tcb(tcb, packet_seq(packet));
+
+ if (s_info.ttl_timer && service_common_update_timer(s_info.ttl_timer, TTL_TIMEOUT) < 0) {
+ ErrPrint("Failed to update timer\n");
+ }
}
break;
s_info.launch_timer = NULL;
}
+ s_info.ttl_timer = service_common_add_timer(tcb_svc_ctx(tcb), TTL_TIMEOUT, ttl_timer_cb, NULL);
+ if (!s_info.ttl_timer) {
+ ErrPrint("Failed to add TTL timer\n");
+ if (s_info.svc_daemon_pid > 0) {
+ ret = aul_terminate_pid(s_info.svc_daemon_pid);
+ ErrPrint("Terminate: %d\n", ret);
+ s_info.svc_daemon_pid = -1;
+ }
+ s_info.svc_daemon_is_launched = 0;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ DbgPrint("TTL Timer is added: %p\n", s_info.ttl_timer);
+
s_info.svc_daemon = tcb;
flush_pended_request();
}
tcb = get_reply_tcb(packet_seq(packet));
if (!tcb) {
ErrPrint("Unable to find reply tcb\n");
- } else {
- ret = service_common_unicast_packet(tcb, packet);
- if (ret < 0)
- ErrPrint("Unable to forward the reply packet\n");
+ break;
+ }
+
+ if (tcb_is_valid(s_info.svc_ctx, tcb) < 0) {
+ ErrPrint("TCB is not valid\n");
+ break;
+ }
+
+ ret = service_common_unicast_packet(tcb, packet);
+ if (ret < 0) {
+ ErrPrint("Unable to forward the reply packet\n");
}
break;
default:
reply_out:
ErrPrint("Error: %d\n", ret);
reply = packet_create_reply(packet, "i", ret);
- if (service_common_unicast_packet(tcb, reply) < 0)
+ if (service_common_unicast_packet(tcb, reply) < 0) {
ErrPrint("Unable to send reply packet\n");
+ }
packet_destroy(reply);
return ret;
}
int utility_service_fini(void)
{
- if (!s_info.svc_ctx)
+ if (!s_info.svc_ctx) {
return LB_STATUS_ERROR_INVALID;
+ }
service_common_destroy(s_info.svc_ctx);
s_info.svc_ctx = NULL;