summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung-jae Park <nicesj.park@samsung.com>2013-06-13 11:05:09 +0900
committerSung-jae Park <nicesj.park@samsung.com>2013-06-13 11:05:17 +0900
commit02c04011dda7ce51a281c1528c07e9fb17ebd219 (patch)
treebff4c35b31c613dac6c268616909618411a8d057
parentc72cf644cec027b9fa656d4f69d39369dc16a3b2 (diff)
parent2af8a6ac30d93ddbc70bbf8c0be3cc3c39a3aa61 (diff)
downloaddata-provider-master-02c04011dda7ce51a281c1528c07e9fb17ebd219.tar.gz
data-provider-master-02c04011dda7ce51a281c1528c07e9fb17ebd219.tar.bz2
data-provider-master-02c04011dda7ce51a281c1528c07e9fb17ebd219.zip
Merge branch 'tizen_2.1' into tizen_2.2
Change-Id: Ia524d02d549ca8c8807490e89e487346492bb651
-rw-r--r--CMakeLists.txt11
-rw-r--r--include/client_life.h2
-rw-r--r--include/debug.h16
-rw-r--r--include/instance.h4
-rw-r--r--include/package.h3
-rw-r--r--include/service_common.h2
-rw-r--r--include/slave_life.h3
-rw-r--r--packaging/data-provider-master.spec13
-rw-r--r--pkgmgr_livebox/src/service_register.c70
-rw-r--r--src/badge_service.c25
-rw-r--r--src/buffer_handler.c12
-rw-r--r--src/client_life.c8
-rw-r--r--src/conf.c5
-rw-r--r--src/critical_log.c22
-rw-r--r--src/dead_monitor.c3
-rw-r--r--src/fault_manager.c3
-rw-r--r--src/fb.c4
-rw-r--r--src/instance.c8
-rw-r--r--src/io.c9
-rw-r--r--src/liveinfo.c15
-rw-r--r--src/main.c55
-rw-r--r--src/notification_service.c27
-rw-r--r--src/package.c59
-rw-r--r--src/parser.c3
-rw-r--r--src/script_handler.c43
-rw-r--r--src/server.c276
-rw-r--r--src/service_common.c94
-rw-r--r--src/setting.c83
-rw-r--r--src/shortcut_service.c26
-rw-r--r--src/slave_life.c62
-rw-r--r--src/slave_rpc.c10
-rw-r--r--src/utility_service.c104
-rw-r--r--src/xmonitor.c8
33 files changed, 884 insertions, 204 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a907636..b7764ee 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,6 +30,7 @@ pkg_check_modules(pkg REQUIRED
livebox-service
notification
badge
+ libsmack
)
SET(PACKAGE "${PROJECT_NAME}")
@@ -48,6 +49,16 @@ ADD_DEFINITIONS("-DCLIENT_SOCKET=\"/opt/usr/share/live_magazine/.client.socket\"
ADD_DEFINITIONS("-DSLAVE_SOCKET=\"/opt/usr/share/live_magazine/.slave.socket\"")
ADD_DEFINITIONS("-DSERVICE_SOCKET=\"/opt/usr/share/live_magazine/.service.socket\"")
+ADD_DEFINITIONS("-DBADGE_SOCKET=\"/tmp/.badge.service\"")
+ADD_DEFINITIONS("-DSHORTCUT_SOCKET=\"/tmp/.shortcut.service\"")
+ADD_DEFINITIONS("-DNOTIFICATION_SOCKET=\"/tmp/.notification.service\"")
+ADD_DEFINITIONS("-DUTILITY_SOCKET=\"/tmp/.utility.service\"")
+
+ADD_DEFINITIONS("-DUTILITY_SMACK_LABEL=\"data-provider-master::utility\"")
+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("-DNDEBUG")
#ADD_DEFINITIONS("-DFLOG")
ADD_DEFINITIONS(${pkg_CFLAGS})
diff --git a/include/client_life.h b/include/client_life.h
index 446b952..66caf9a 100644
--- a/include/client_life.h
+++ b/include/client_life.h
@@ -62,7 +62,7 @@ extern int client_count(void);
* \note
* For dead signal handler
*/
-extern int client_deactivated_by_fault(struct client_node *client);
+extern struct client_node *client_deactivated_by_fault(struct client_node *client);
extern void client_reset_fault(struct client_node *client);
extern const int const client_is_faulted(const struct client_node *client);
diff --git a/include/debug.h b/include/debug.h
index fb7c780..0929bf0 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -14,9 +14,21 @@
* limitations under the License.
*/
+#if !defined(SECURE_LOGD)
+#define SECURE_LOGD LOGD
+#endif
+
+#if !defined(SECURE_LOGE)
+#define SECURE_LOGE LOGE
+#endif
+
+#if !defined(SECURE_LOGW)
+#define SECURE_LOGW LOGW
+#endif
+
#if !defined(FLOG)
-#define DbgPrint(format, arg...) LOGD("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
-#define ErrPrint(format, arg...) LOGE("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
+#define DbgPrint(format, arg...) SECURE_LOGD("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...) SECURE_LOGE("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg)
#else
extern FILE *__file_log_fp;
#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
diff --git a/include/instance.h b/include/instance.h
index c21e58c..54ba80a 100644
--- a/include/instance.h
+++ b/include/instance.h
@@ -229,8 +229,8 @@ extern int instance_del_client(struct inst_info *inst, struct client_node *clien
extern int instance_has_client(struct inst_info *inst, struct client_node *client);
extern void *instance_client_list(struct inst_info *inst);
-extern void instance_init(void);
-extern void instance_fini(void);
+extern int instance_init(void);
+extern int instance_fini(void);
extern int instance_event_callback_add(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data), void *data);
extern int instance_event_callback_del(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data));
diff --git a/include/package.h b/include/package.h
index 488f465..330628f 100644
--- a/include/package.h
+++ b/include/package.h
@@ -99,6 +99,7 @@ extern void package_set_pd_height(struct pkg_info *info, int height);
extern void package_set_pd_width(struct pkg_info *info, int width);
extern int package_set_abi(struct pkg_info *info, const char *abi);
extern void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *info);
+extern void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info);
/*!
* \brief
@@ -124,4 +125,6 @@ extern int const package_fault_count(struct pkg_info *info);
extern int package_init(void);
extern int package_fini(void);
+extern int package_is_enabled(const char *appid);
+
/* End of a file */
diff --git a/include/service_common.h b/include/service_common.h
index eb6e385..eaa06ea 100644
--- a/include/service_common.h
+++ b/include/service_common.h
@@ -37,4 +37,6 @@ extern int service_common_unicast_packet(struct tcb *tcb, struct packet *packet)
extern struct service_event_item *service_common_add_timer(struct service_context *svc_ctx, double timer, int (*timer_cb)(struct service_context *svc_cx, void *data), void *data);
extern int service_common_del_timer(struct service_context *svc_ctx, struct service_event_item *item);
+extern int service_common_fd(struct service_context *ctx);
+
/* End of a file */
diff --git a/include/slave_life.h b/include/slave_life.h
index dea9f27..d294520 100644
--- a/include/slave_life.h
+++ b/include/slave_life.h
@@ -193,4 +193,7 @@ extern int slave_need_to_reactivate(struct slave_node *slave);
extern int slave_network(const struct slave_node *slave);
extern void slave_set_network(struct slave_node *slave, int network);
+extern int slave_deactivate_all(int reactivate, int reactivate_instances);
+extern int slave_activate_all(void);
+
/* End of a file */
diff --git a/packaging/data-provider-master.spec b/packaging/data-provider-master.spec
index ba1be6a..0b806f2 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.23.5
+Version: 0.24.7
Release: 1
Group: HomeTF/Livebox
License: Flora License
@@ -14,6 +14,7 @@ BuildRequires: pkgconfig(sqlite3)
BuildRequires: pkgconfig(db-util)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(libsmack)
BuildRequires: pkgconfig(bundle)
BuildRequires: pkgconfig(ecore-x)
BuildRequires: pkgconfig(ecore)
@@ -34,6 +35,7 @@ BuildRequires: pkgconfig(pkgmgr)
BuildRequires: pkgconfig(livebox-service)
BuildRequires: pkgconfig(notification)
BuildRequires: pkgconfig(badge)
+BuildRequires: pkgconfig(security-server)
%description
Manage the 2nd stage livebox service provider and communicate with the viewer application.
@@ -60,7 +62,7 @@ mkdir -p %{buildroot}/%{_sysconfdir}/rc.d/rc3.d
mkdir -p %{buildroot}/%{_libdir}/systemd/user/tizen-middleware.target.wants
touch %{buildroot}/opt/dbspace/.livebox.db
touch %{buildroot}/opt/dbspace/.livebox.db-journal
-ln -sf %{_sysconfdir}/rc.d/init.d/data-provider-master %{buildroot}/%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master
+#ln -sf %{_sysconfdir}/rc.d/init.d/data-provider-master %{buildroot}/%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master
ln -sf %{_libdir}/systemd/user/data-provider-master.service %{buildroot}/%{_libdir}/systemd/user/tizen-middleware.target.wants/data-provider-master.service
%pre
@@ -90,7 +92,7 @@ echo "%{_sysconfdir}/init.d/data-provider-master start"
%manifest data-provider-master.manifest
%defattr(-,root,root,-)
%{_sysconfdir}/rc.d/init.d/data-provider-master
-%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master
+#%{_sysconfdir}/rc.d/rc3.d/S99data-provider-master
%{_bindir}/data-provider-master
%{_bindir}/liveinfo
%{_prefix}/etc/package-manager/parserlib/*
@@ -98,10 +100,7 @@ echo "%{_sysconfdir}/init.d/data-provider-master start"
%{_libdir}/systemd/user/data-provider-master.service
%{_libdir}/systemd/user/tizen-middleware.target.wants/data-provider-master.service
%{_datarootdir}/license/*
-/opt/usr/share/live_magazine
-/opt/usr/share/live_magazine/log
-/opt/usr/share/live_magazine/reader
-/opt/usr/share/live_magazine/always
+/opt/usr/share/live_magazine/*
/opt/dbspace/.livebox.db
/opt/dbspace/.livebox.db-journal
diff --git a/pkgmgr_livebox/src/service_register.c b/pkgmgr_livebox/src/service_register.c
index 78bc0d6..dd725cb 100644
--- a/pkgmgr_livebox/src/service_register.c
+++ b/pkgmgr_livebox/src/service_register.c
@@ -32,9 +32,21 @@
#include "dlist.h"
+#if !defined(SECURE_LOGD)
+#define SECURE_LOGD LOGD
+#endif
+
+#if !defined(SECURE_LOGE)
+#define SECURE_LOGE LOGE
+#endif
+
+#if !defined(SECURE_LOGW)
+#define SECURE_LOGW LOGW
+#endif
+
#if !defined(FLOG)
-#define DbgPrint(format, arg...) LOGD("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
-#define ErrPrint(format, arg...) LOGE("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define DbgPrint(format, arg...) SECURE_LOGD("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...) SECURE_LOGE("[%s/%s:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
#endif
/* End of a file */
@@ -43,12 +55,12 @@
* DB Table schema
*
* pkgmap
- * +-------+-------+---------+
- * | appid | pkgid | prime |
- * +-------+-------+---------+
- * | - | - | |
- * +-------+-------+---------+
- * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER )
+ * +-------+-------+-------+-------+
+ * | appid | pkgid | uiapp | prime |
+ * +-------+-------+-------+-------+
+ * | - | - | - | - |
+ * +-------+-------+-------+-------+
+ * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER )
*
*
* provider
@@ -165,6 +177,7 @@ struct livebox {
xmlChar *script; /* Script engine */
xmlChar *content; /* Content information */
xmlChar *setup;
+ xmlChar *uiapp; /* UI App Id */
int pinup; /* Is this support the pinup feature? */
int primary; /* Is this primary livebox? */
@@ -284,7 +297,7 @@ static inline int db_create_pkgmap(void)
char *err;
static const char *ddl;
- ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER )";
+ ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER )";
if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
ErrPrint("Failed to execute the DDL (%s)\n", err);
return -EIO;
@@ -296,13 +309,16 @@ static inline int db_create_pkgmap(void)
return 0;
}
-static inline int db_insert_pkgmap(const char *appid, const char *pkgid, int primary)
+static inline int db_insert_pkgmap(const char *appid, const char *pkgid, const char *uiappid, int primary)
{
int ret;
static const char *dml;
sqlite3_stmt *stmt;
- dml = "INSERT INTO pkgmap ( appid, pkgid, prime ) VALUES (? ,?, ?)";
+ if (!uiappid)
+ uiappid = ""; /*!< Could we replace this with Main AppId of this package? */
+
+ dml = "INSERT INTO pkgmap ( appid, pkgid, uiapp, prime ) VALUES (? ,?, ?, ?)";
ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
if (ret != SQLITE_OK) {
DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
@@ -323,7 +339,14 @@ static inline int db_insert_pkgmap(const char *appid, const char *pkgid, int pri
goto out;
}
- ret = sqlite3_bind_int(stmt, 3, primary);
+ ret = sqlite3_bind_text(stmt, 3, uiappid, -1, SQLITE_TRANSIENT);
+ if (ret != SQLITE_OK) {
+ DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
+ ret = -EIO;
+ goto out;
+ }
+
+ ret = sqlite3_bind_int(stmt, 4, primary);
if (ret != SQLITE_OK) {
DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
ret = -EIO;
@@ -1657,6 +1680,22 @@ static inline void update_launch(struct livebox *livebox, xmlNodePtr node)
}
}
+static inline void update_ui_appid(struct livebox *livebox, xmlNodePtr node)
+{
+ xmlChar *uiapp;
+ uiapp = xmlNodeGetContent(node);
+ if (!uiapp) {
+ DbgPrint("Has no valid ui-appid\n");
+ return;
+ }
+
+ livebox->uiapp = xmlStrdup(uiapp);
+ if (!livebox->uiapp) {
+ ErrPrint("Failed to duplicate string: %s\n", (char *)uiapp);
+ return;
+ }
+}
+
static inline void update_setup(struct livebox *livebox, xmlNodePtr node)
{
xmlChar *setup;
@@ -2135,7 +2174,7 @@ static inline int db_insert_livebox(struct livebox *livebox, const char *appid)
struct option *option;
begin_transaction();
- ret = db_insert_pkgmap(appid, (char *)livebox->pkgid, livebox->primary);
+ ret = db_insert_pkgmap(appid, (char *)livebox->pkgid, (char *)livebox->uiapp, livebox->primary);
if (ret < 0)
goto errout;
@@ -2450,6 +2489,11 @@ static inline int do_install(xmlNodePtr node, const char *appid)
update_launch(livebox, node);
continue;
}
+
+ if (!xmlStrcasecmp(node->name, (const xmlChar *)"ui-appid")) {
+ update_ui_appid(livebox, node);
+ continue;
+ }
}
return db_insert_livebox(livebox, appid);
diff --git a/src/badge_service.c b/src/badge_service.c
index 2001bc0..96050f3 100644
--- a/src/badge_service.c
+++ b/src/badge_service.c
@@ -22,6 +22,8 @@
#include <livebox-errno.h>
#include <packet.h>
+#include <sys/smack.h>
+
#include <badge.h>
#include <badge_db.h>
@@ -30,8 +32,6 @@
#include "util.h"
#include "conf.h"
-#define BADGE_ADDR "/tmp/.badge.service"
-
static struct info {
Eina_List *context_list;
struct service_context *svc_ctx;
@@ -367,12 +367,30 @@ HAPI int badge_service_init(void)
return LB_STATUS_ERROR_ALREADY;
}
- s_info.svc_ctx = service_common_create(BADGE_ADDR, service_thread_main, NULL);
+ s_info.svc_ctx = service_common_create(BADGE_SOCKET, service_thread_main, NULL);
if (!s_info.svc_ctx) {
ErrPrint("Unable to activate service thread\n");
return LB_STATUS_ERROR_FAULT;
}
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
DbgPrint("Successfully initiated\n");
return LB_STATUS_SUCCESS;
}
@@ -383,6 +401,7 @@ HAPI int badge_service_fini(void)
return LB_STATUS_ERROR_INVALID;
service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
DbgPrint("Successfully finalized\n");
return LB_STATUS_SUCCESS;
}
diff --git a/src/buffer_handler.c b/src/buffer_handler.c
index 79d3c83..79e5c20 100644
--- a/src/buffer_handler.c
+++ b/src/buffer_handler.c
@@ -1250,7 +1250,8 @@ HAPI void buffer_handler_flush(struct buffer_info *info)
if (write(fd, info->buffer, size) != size)
ErrPrint("Write is not completed: %s\n", strerror(errno));
- close(fd);
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
} else {
DbgPrint("Flush nothing\n");
}
@@ -1304,7 +1305,8 @@ HAPI int buffer_handler_init(void)
DbgPrint("DRM Magic: 0x%X\n", magic);
if (!DRI2Authenticate(ecore_x_display_get(), DefaultRootWindow(ecore_x_display_get()), (unsigned int)magic)) {
DbgPrint("Failed to do authenticate for DRI2\n");
- close(s_info.fd);
+ if (close(s_info.fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
s_info.fd = -1;
s_info.evt_base = 0;
s_info.err_base = 0;
@@ -1314,7 +1316,8 @@ HAPI int buffer_handler_init(void)
s_info.slp_bufmgr = tbm_bufmgr_init(s_info.fd);
if (!s_info.slp_bufmgr) {
DbgPrint("Failed to init bufmgr\n");
- close(s_info.fd);
+ if (close(s_info.fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
s_info.fd = -1;
s_info.evt_base = 0;
s_info.err_base = 0;
@@ -1327,7 +1330,8 @@ HAPI int buffer_handler_init(void)
HAPI int buffer_handler_fini(void)
{
if (s_info.fd >= 0) {
- close(s_info.fd);
+ if (close(s_info.fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
s_info.fd = -1;
}
diff --git a/src/client_life.c b/src/client_life.c
index d30417a..dd0e49c 100644
--- a/src/client_life.c
+++ b/src/client_life.c
@@ -370,17 +370,17 @@ HAPI int client_count(void)
return eina_list_count(s_info.client_list);
}
-HAPI int client_deactivated_by_fault(struct client_node *client)
+HAPI struct client_node *client_deactivated_by_fault(struct client_node *client)
{
if (!client || client->faulted)
- return 0;
+ return client;
ErrPrint("Client[%p] is faulted(%d), pid(%d)\n", client, client->refcnt, client->pid);
client->faulted = 1;
client->pid = (pid_t)-1;
invoke_deactivated_cb(client);
- (void)client_destroy(client);
+ client = client_destroy(client);
/*!
* \todo
* Who invokes this function has to care the reference counter of a client
@@ -388,7 +388,7 @@ HAPI int client_deactivated_by_fault(struct client_node *client)
* client->pid = (pid_t)-1;
* slave_unref(client)
*/
- return 0;
+ return client;
}
HAPI const int const client_is_faulted(const struct client_node *client)
diff --git a/src/conf.c b/src/conf.c
index 4c7bd7f..1c05206 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -517,7 +517,7 @@ HAPI int conf_loader(void)
do {
c = getc(fp);
if ((c == EOF) && (state == VALUE)) {
- LOGD("[%s:%d] VALUE state EOF\n", __func__, __LINE__);
+ DbgPrint("[%s:%d] VALUE state EOF\n", __func__, __LINE__);
state = END;
}
@@ -662,7 +662,8 @@ HAPI int conf_loader(void)
linelen++;
} while (c != EOF);
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
return LB_STATUS_SUCCESS;
}
diff --git a/src/critical_log.c b/src/critical_log.c
index 7469013..75a9796 100644
--- a/src/critical_log.c
+++ b/src/critical_log.c
@@ -23,6 +23,7 @@
#include <libgen.h>
#include <sys/types.h>
#include <unistd.h>
+#include <pthread.h>
#include <dlog.h>
#include <Eina.h>
@@ -38,11 +39,13 @@ static struct {
int file_id;
int nr_of_lines;
char *filename;
+ pthread_mutex_t cri_lock;
} s_info = {
.fp = NULL,
.file_id = 0,
.nr_of_lines = 0,
.filename = NULL,
+ .cri_lock = PTHREAD_MUTEX_INITIALIZER,
};
@@ -62,8 +65,10 @@ static inline void rotate_log(void)
if (filename) {
snprintf(filename, namelen, "%s/%d_%s.%d", SLAVE_LOG_PATH, s_info.file_id, s_info.filename, getpid());
- if (s_info.fp)
- fclose(s_info.fp);
+ if (s_info.fp) {
+ if (fclose(s_info.fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
+ }
s_info.fp = fopen(filename, "w+");
if (!s_info.fp)
@@ -81,10 +86,15 @@ 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));
+
fprintf(s_info.fp, "%lf [%s:%d] ", util_timestamp(), util_basename((char *)func), line);
va_start(ap, fmt);
@@ -95,6 +105,11 @@ 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));
+
return ret;
}
@@ -149,7 +164,8 @@ HAPI void critical_log_fini(void)
}
if (s_info.fp) {
- fclose(s_info.fp);
+ if (fclose(s_info.fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
s_info.fp = NULL;
}
}
diff --git a/src/dead_monitor.c b/src/dead_monitor.c
index a768f39..adea7d3 100644
--- a/src/dead_monitor.c
+++ b/src/dead_monitor.c
@@ -55,8 +55,9 @@ static int evt_cb(int handle, void *data)
client = client_find_by_rpc_handle(handle);
if (client) {
if (client_pid(client) != (pid_t)-1)
- client_deactivated_by_fault(client);
+ client = client_deactivated_by_fault(client);
+ DbgPrint("Client pointer: %p (0 means deleted)\n", client);
return 0;
}
diff --git a/src/fault_manager.c b/src/fault_manager.c
index 86b61c0..7e44685 100644
--- a/src/fault_manager.c
+++ b/src/fault_manager.c
@@ -83,7 +83,8 @@ static char *check_log_file(struct slave_node *slave)
}
ptr = fgets(pkgname, sizeof(pkgname), fp);
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
if (ptr != pkgname) {
ErrPrint("Invalid log\n");
return NULL;
diff --git a/src/fb.c b/src/fb.c
index 0907537..e3f4f0d 100644
--- a/src/fb.c
+++ b/src/fb.c
@@ -115,14 +115,14 @@ static void sw_render_post_cb(void *data, Evas *e, void *event_info)
internal_ee = ecore_evas_ecore_evas_get(e);
if (!internal_ee) {
- LOGD("Failed to get ecore evas\n");
+ ErrPrint("Failed to get ecore evas\n");
return;
}
// Get a pointer of a buffer of the virtual canvas
canvas = (void*)ecore_evas_buffer_pixels_get(internal_ee);
if (!canvas) {
- LOGD("Failed to get pixel canvas\n");
+ ErrPrint("Failed to get pixel canvas\n");
return;
}
diff --git a/src/instance.c b/src/instance.c
index 25a0a11..8bf38f9 100644
--- a/src/instance.c
+++ b/src/instance.c
@@ -3031,16 +3031,20 @@ HAPI void *instance_client_list(struct inst_info *inst)
return inst->client_list;
}
-HAPI void instance_init(void)
+HAPI int instance_init(void)
{
if (!strcasecmp(PROVIDER_METHOD, "shm"))
s_info.env_buf_type = BUFFER_TYPE_SHM;
else if (!strcasecmp(PROVIDER_METHOD, "pixmap"))
s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
+ /* Default method is BUFFER_TYPE_FILE */
+
+ return LB_STATUS_SUCCESS;
}
-HAPI void instance_fini(void)
+HAPI int instance_fini(void)
{
+ return LB_STATUS_SUCCESS;
}
static inline struct tag_item *find_tag_item(struct inst_info *inst, const char *tag)
diff --git a/src/io.c b/src/io.c
index fee17f2..e4ad05c 100644
--- a/src/io.c
+++ b/src/io.c
@@ -208,7 +208,8 @@ static inline int load_abi_table(void)
}
}
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
return LB_STATUS_SUCCESS;
}
@@ -700,12 +701,14 @@ HAPI int io_crawling_liveboxes(int (*cb)(const char *pkgname, int prime, void *d
continue;
if (cb(ent->d_name, -1, data) < 0) {
- closedir(dir);
+ if (closedir(dir) < 0)
+ ErrPrint("closedir: %s\n", strerror(errno));
return LB_STATUS_ERROR_CANCEL;
}
}
- closedir(dir);
+ if (closedir(dir) < 0)
+ ErrPrint("closedir: %s\n", strerror(errno));
}
return LB_STATUS_SUCCESS;
diff --git a/src/liveinfo.c b/src/liveinfo.c
index 3f76531..c81a3e9 100644
--- a/src/liveinfo.c
+++ b/src/liveinfo.c
@@ -58,8 +58,10 @@ HAPI void liveinfo_fini(void)
struct liveinfo *info;
EINA_LIST_FREE(s_info.info_list, info) {
- fclose(info->fp);
- unlink(info->fifo_name);
+ if (fclose(info->fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
+ if (unlink(info->fifo_name) < 0)
+ ErrPrint("unlink: %s\n", strerror(errno));
DbgFree(info);
}
}
@@ -105,7 +107,8 @@ HAPI struct liveinfo *liveinfo_create(pid_t pid, int handle)
snprintf(info->fifo_name, sizeof(info->fifo_name), "/tmp/.live_info.%lf", util_timestamp());
if (mkfifo(info->fifo_name, 0644) < 0) {
ErrPrint("mkfifo: %s\n", strerror(errno));
- unlink(info->fifo_name);
+ if (unlink(info->fifo_name) < 0)
+ ErrPrint("unlink: %s\n", strerror(errno));
DbgFree(info);
return NULL;
}
@@ -134,7 +137,8 @@ HAPI int liveinfo_open_fifo(struct liveinfo *info)
HAPI void liveinfo_close_fifo(struct liveinfo *info)
{
if (info->fp) {
- fclose(info->fp);
+ if (fclose(info->fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
info->fp = NULL;
}
}
@@ -143,7 +147,8 @@ HAPI void liveinfo_destroy(struct liveinfo *info)
{
s_info.info_list = eina_list_remove(s_info.info_list, info);
liveinfo_close_fifo(info);
- unlink(info->fifo_name);
+ if (unlink(info->fifo_name) < 0)
+ ErrPrint("unlink: %s\n", strerror(errno));
DbgFree(info);
}
diff --git a/src/main.c b/src/main.c
index a235299..b8441bf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -132,8 +132,11 @@ static inline int app_terminate(void)
{
int ret;
- ret = script_fini();
- DbgPrint("script: %d\n", ret);
+ ret = server_fini();
+ DbgPrint("Finalize server: %d\n", ret);
+
+ ret = dead_fini();
+ DbgPrint("dead signal handler finalized: %d\n", ret);
ret = utility_service_fini();
DbgPrint("utility: %d\n", ret);
@@ -153,23 +156,21 @@ static inline int app_terminate(void)
ret = setting_fini();
DbgPrint("Finalize setting : %d\n", ret);
- ret = buffer_handler_fini();
- DbgPrint("buffer handler: %d\n", ret);
-
- xmonitor_fini();
-
- instance_fini();
+ ret = instance_fini();
+ DbgPrint("Finalizing instances: %d\n", ret);
ret = package_fini();
DbgPrint("Finalize package info: %d\n", ret);
- client_fini();
+ ret = script_fini();
+ DbgPrint("script: %d\n", ret);
- ret = server_fini();
- DbgPrint("Finalize dbus: %d\n", ret);
+ ret = buffer_handler_fini();
+ DbgPrint("buffer handler: %d\n", ret);
- ret = dead_fini();
- DbgPrint("dead signal handler finalized: %d\n", ret);
+ xmonitor_fini();
+
+ client_fini();
ret = io_fini();
DbgPrint("IO finalized: %d\n", ret);
@@ -209,8 +210,22 @@ static Eina_Bool signal_cb(void *data, Ecore_Fd_Handler *handler)
ErrPrint("stop.provider: %s\n", strerror(errno));
vconf_set_bool(VCONFKEY_MASTER_STARTED, 0);
- exit(0);
- //ecore_main_loop_quit();
+ //exit(0);
+ ecore_main_loop_quit();
+ } else if (fdsi.ssi_signo == SIGUSR1) {
+ /*!
+ * Turn off auto-reactivation
+ * Terminate all slaves
+ */
+ CRITICAL_LOG("USRS1, Deactivate ALL\n");
+ slave_deactivate_all(0, 1);
+ } else if (fdsi.ssi_signo == SIGUSR2) {
+ /*!
+ * Turn on auto-reactivation
+ * Launch all slaves again
+ */
+ CRITICAL_LOG("USR2, Activate ALL\n");
+ slave_activate_all();
} else {
CRITICAL_LOG("Unknown SIG[%d] received\n", fdsi.ssi_signo);
}
@@ -259,6 +274,14 @@ int main(int argc, char *argv[])
if (ret < 0)
CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
+ ret = sigaddset(&mask, SIGUSR1);
+ if (ret < 0)
+ CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
+
+ ret = sigaddset(&mask, SIGUSR2);
+ if (ret < 0)
+ CRITICAL_LOG("Failed to do sigemptyset: %s\n", strerror(errno));
+
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
if (ret < 0)
CRITICAL_LOG("Failed to mask the SIGTERM: %s\n", strerror(errno));
@@ -309,8 +332,8 @@ int main(int argc, char *argv[])
app_terminate();
- ecore_evas_shutdown();
evas_shutdown();
+ ecore_evas_shutdown();
ecore_x_shutdown();
diff --git a/src/notification_service.c b/src/notification_service.c
index 12da940..fec5fa4 100644
--- a/src/notification_service.c
+++ b/src/notification_service.c
@@ -21,6 +21,8 @@
#include <livebox-errno.h>
#include <packet.h>
+#include <sys/smack.h>
+
#include <notification_ipc.h>
#include <notification_noti.h>
#include <notification_error.h>
@@ -30,10 +32,6 @@
#include "util.h"
#include "conf.h"
-#ifndef NOTIFICATION_ADDR
-#define NOTIFICATION_ADDR "/tmp/.notification.service"
-#endif
-
#ifndef NOTIFICATION_DEL_PACKET_UNIT
#define NOTIFICATION_DEL_PACKET_UNIT 10
#endif
@@ -438,12 +436,30 @@ HAPI int notification_service_init(void)
return LB_STATUS_ERROR_ALREADY;
}
- s_info.svc_ctx = service_common_create(NOTIFICATION_ADDR, service_thread_main, NULL);
+ s_info.svc_ctx = service_common_create(NOTIFICATION_SOCKET, service_thread_main, NULL);
if (!s_info.svc_ctx) {
ErrPrint("Unable to activate service thread\n");
return LB_STATUS_ERROR_FAULT;
}
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), NOTIFICATION_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), NOTIFICATION_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
DbgPrint("Successfully initiated\n");
return LB_STATUS_SUCCESS;
}
@@ -454,6 +470,7 @@ HAPI int notification_service_fini(void)
return LB_STATUS_ERROR_INVALID;
service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
DbgPrint("Successfully Finalized\n");
return LB_STATUS_SUCCESS;
}
diff --git a/src/package.c b/src/package.c
index 188c170..017488e 100644
--- a/src/package.c
+++ b/src/package.c
@@ -25,7 +25,9 @@
#include <packet.h>
#include <livebox-errno.h>
+#include <ail.h>
+#include "critical_log.h"
#include "debug.h"
#include "util.h"
#include "parser.h"
@@ -279,6 +281,11 @@ static int slave_resumed_cb(struct slave_node *slave, void *data)
static inline void destroy_package(struct pkg_info *info)
{
+ struct context_info *ctx_info;
+ EINA_LIST_FREE(info->ctx_list, ctx_info) {
+ /* This items will be deleted from group_del_livebox */
+ }
+
group_del_livebox(info->pkgname);
package_clear_fault(info);
@@ -541,6 +548,11 @@ HAPI void package_add_ctx_info(struct pkg_info *pkginfo, struct context_info *in
pkginfo->ctx_list = eina_list_append(pkginfo->ctx_list, info);
}
+HAPI void package_del_ctx_info(struct pkg_info *pkginfo, struct context_info *info)
+{
+ pkginfo->ctx_list = eina_list_remove(pkginfo->ctx_list, info);
+}
+
HAPI char *package_lb_pkgname(const char *pkgname)
{
char *lb_pkgname;
@@ -633,11 +645,11 @@ HAPI int package_dump_fault_info(struct pkg_info *info)
if (!info->fault_info)
return LB_STATUS_ERROR_NOT_EXIST;
- ErrPrint("=============\n");
- ErrPrint("faulted at %lf\n", info->fault_info->timestamp);
- ErrPrint("Package: %s\n", info->pkgname);
- ErrPrint("Function: %s\n", info->fault_info->function);
- ErrPrint("InstanceID: %s\n", info->fault_info->filename);
+ CRITICAL_LOG("=============\n");
+ CRITICAL_LOG("faulted at %lf\n", info->fault_info->timestamp);
+ CRITICAL_LOG("Package: %s\n", info->pkgname);
+ CRITICAL_LOG("Function: %s\n", info->fault_info->function);
+ CRITICAL_LOG("InstanceID: %s\n", info->fault_info->filename);
return LB_STATUS_SUCCESS;
}
@@ -1361,11 +1373,28 @@ HAPI int package_init(void)
HAPI int package_fini(void)
{
+ Eina_List *p_l;
+ Eina_List *p_n;
+ Eina_List *i_l;
+ Eina_List *i_n;
+ struct pkg_info *info;
+ struct inst_info *inst;
+
pkgmgr_del_event_callback(PKGMGR_EVENT_INSTALL, install_cb, NULL);
pkgmgr_del_event_callback(PKGMGR_EVENT_UNINSTALL, uninstall_cb, NULL);
pkgmgr_del_event_callback(PKGMGR_EVENT_UPDATE, update_cb, NULL);
pkgmgr_fini();
client_global_event_handler_del(CLIENT_GLOBAL_EVENT_CREATE, client_created_cb, NULL);
+
+ EINA_LIST_FOREACH_SAFE(s_info.pkg_list, p_l, p_n, info) {
+ EINA_LIST_FOREACH_SAFE(info->inst_list, i_l, i_n, inst) {
+ instance_state_reset(inst);
+ instance_destroy(inst);
+ }
+
+ package_destroy(info);
+ }
+
return 0;
}
@@ -1475,4 +1504,24 @@ HAPI int const package_fault_count(struct pkg_info *info)
return info ? info->fault_count : 0;
}
+HAPI int package_is_enabled(const char *appid)
+{
+ ail_appinfo_h ai;
+ bool enabled;
+ int ret;
+
+ ret = ail_get_appinfo(appid, &ai);
+ if (ret != AIL_ERROR_OK) {
+ ErrPrint("Unable to get appinfo: %d\n", ret);
+ return 0;
+ }
+
+ if (ail_appinfo_get_bool(ai, AIL_PROP_X_SLP_ENABLED_BOOL, &enabled) != AIL_ERROR_OK)
+ enabled = false;
+
+ ail_destroy_appinfo(ai);
+
+ return enabled == true;
+}
+
/* End of a file */
diff --git a/src/parser.c b/src/parser.c
index 948aec8..987772c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -820,7 +820,8 @@ HAPI struct parser *parser_load(const char *pkgname)
linelen++;
} while (c != EOF);
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
s_list = eina_list_append(s_list, item);
return item;
diff --git a/src/script_handler.c b/src/script_handler.c
index ff554bc..9811312 100644
--- a/src/script_handler.c
+++ b/src/script_handler.c
@@ -396,6 +396,8 @@ HAPI struct script_info *script_handler_create(struct inst_info *inst, const cha
HAPI int script_handler_destroy(struct script_info *info)
{
struct block *block;
+ int ret;
+
if (!info || !info->port) {
ErrPrint("port is not valid\n");
return LB_STATUS_ERROR_INVALID;
@@ -406,8 +408,9 @@ HAPI int script_handler_destroy(struct script_info *info)
return LB_STATUS_ERROR_INVALID;
}
- if (info->port->destroy(info->port_data) < 0)
- ErrPrint("Failed to destroy port, but go ahead\n");
+ ret = info->port->destroy(info->port_data);
+ if (ret < 0)
+ ErrPrint("Failed to destroy port, but go ahead: %d\n", ret);
fb_destroy(info->fb);
@@ -863,7 +866,7 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch
return LB_STATUS_ERROR_IO;
}
- DbgPrint("Parsing %s\n", descfile);
+ DbgPrint("Start parsing %s\n", descfile);
state = UNKNOWN;
field_idx = 0;
@@ -884,7 +887,8 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch
if (!isspace(ch) && ch != EOF) {
ErrPrint("%d: Syntax error: Desc is not started with '{' or space - (%c = 0x%x)\n", lineno, ch, ch);
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
return LB_STATUS_ERROR_INVALID;
}
break;
@@ -901,7 +905,8 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch
block = calloc(1, sizeof(*block));
if (!block) {
ErrPrint("Heap: %s\n", strerror(errno));
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
return LB_STATUS_ERROR_MEMORY;
}
@@ -1209,14 +1214,16 @@ HAPI int script_handler_parse_desc(const char *pkgname, const char *id, const ch
goto errout;
}
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
return LB_STATUS_SUCCESS;
errout:
ErrPrint("Parse error at %d file %s\n", lineno, util_basename(descfile));
if (block)
delete_block(block);
- fclose(fp);
+ if (fclose(fp) != 0)
+ ErrPrint("fclose: %s\n", strerror(errno));
return LB_STATUS_ERROR_INVALID;
}
@@ -1247,7 +1254,8 @@ HAPI int script_init(void)
path = malloc(pathlen);
if (!path) {
ErrPrint("Heap: %s %d\n", strerror(errno), pathlen);
- closedir(dir);
+ if (closedir(dir) < 0)
+ ErrPrint("closedir: %s\n", strerror(errno));
return LB_STATUS_ERROR_MEMORY;
}
@@ -1257,7 +1265,8 @@ HAPI int script_init(void)
if (!item) {
ErrPrint("Heap: %s\n", strerror(errno));
DbgFree(path);
- closedir(dir);
+ if (closedir(dir) < 0)
+ ErrPrint("closedir: %s\n", strerror(errno));
return LB_STATUS_ERROR_MEMORY;
}
@@ -1267,7 +1276,8 @@ HAPI int script_init(void)
if (!item->handle) {
ErrPrint("Error: %s\n", dlerror());
DbgFree(item);
- closedir(dir);
+ if (closedir(dir) < 0)
+ ErrPrint("closedir: %s\n", strerror(errno));
return LB_STATUS_ERROR_FAULT;
}
@@ -1349,14 +1359,18 @@ HAPI int script_init(void)
s_info.script_port_list = eina_list_append(s_info.script_port_list, item);
}
- closedir(dir);
+ if (closedir(dir) < 0)
+ ErrPrint("closedir: %s\n", strerror(errno));
+
return LB_STATUS_SUCCESS;
errout:
ErrPrint("Error: %s\n", dlerror());
- dlclose(item->handle);
+ if (dlclose(item->handle) != 0)
+ ErrPrint("dlclose: %s\n", strerror(errno));
DbgFree(item);
- closedir(dir);
+ if (closedir(dir) < 0)
+ ErrPrint("closedir: %s\n", strerror(errno));
return LB_STATUS_ERROR_FAULT;
}
@@ -1368,7 +1382,8 @@ HAPI int script_fini(void)
*/
EINA_LIST_FREE(s_info.script_port_list, item) {
item->fini();
- dlclose(item->handle);
+ if (dlclose(item->handle) != 0)
+ ErrPrint("dlclose: %s\n", strerror(errno));
DbgFree(item);
}
diff --git a/src/server.c b/src/server.c
index 517a4da..07aad34 100644
--- a/src/server.c
+++ b/src/server.c
@@ -23,12 +23,14 @@
#include <Ecore_Evas.h> /* fb.h */
#include <aul.h>
#include <Ecore.h>
+#include <ail.h>
#include <packet.h>
#include <com-core_packet.h>
#include <livebox-errno.h>
#include <livebox-service.h>
+#include "critical_log.h"
#include "conf.h"
#include "debug.h"
#include "server.h"
@@ -497,6 +499,40 @@ static Eina_Bool lazy_delete_cb(void *data)
return ECORE_CALLBACK_CANCEL;
}
+/*
+static inline void clear_pd_monitor(struct inst_info *inst)
+{
+ Ecore_Timer *pd_monitor;
+
+ pd_monitor = instance_del_data(inst, "pd,open,monitor");
+ if (pd_monitor) {
+ DbgPrint("Clear pd,open,monitor\n");
+ (void)instance_client_pd_created(inst, LB_STATUS_SUCCESS);
+ ecore_timer_del(pd_monitor);
+ (void)instance_unref(inst);
+ return;
+ }
+
+ pd_monitor = instance_del_data(inst, "pd,close,monitor");
+ if (pd_monitor) {
+ DbgPrint("Clear pd,close,monitor\n");
+ (void)instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS);
+ ecore_timer_del(pd_monitor);
+ (void)instance_unref(inst);
+ return;
+ }
+
+ pd_monitor = instance_del_data(inst, "pd,resize,monitor");
+ if (pd_monitor) {
+ DbgPrint("Clear pd,resize,monitor\n");
+ (void)instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS);
+ ecore_timer_del(pd_monitor);
+ (void)instance_unref(inst);
+ return;
+ }
+}
+*/
+
static struct packet *client_delete(pid_t pid, int handle, const struct packet *packet) /* pid, pkgname, filename, ret */
{
struct client_node *client;
@@ -549,6 +585,7 @@ static struct packet *client_delete(pid_t pid, int handle, const struct packet *
* So We have to make a delay to send a deleted event.
*/
+ DbgPrint("Client has PD\n");
item->client = client_ref(client);
item->inst = instance_ref(inst);
@@ -563,9 +600,12 @@ static struct packet *client_delete(pid_t pid, int handle, const struct packet *
}
}
} else {
+ DbgPrint("Client has no permission\n");
ret = LB_STATUS_ERROR_PERMISSION;
}
} else {
+ DbgPrint("Ok. destroy instance\n");
+ //clear_pd_monitor(inst);
ret = instance_destroy(inst);
}
@@ -641,6 +681,7 @@ static struct packet *client_new(pid_t pid, int handle, const struct packet *pac
int width;
int height;
char *lb_pkgname;
+ char *mainappid;
client = client_find_by_pid(pid);
if (!client) {
@@ -666,6 +707,15 @@ static struct packet *client_new(pid_t pid, int handle, const struct packet *pac
goto out;
}
+ mainappid = livebox_service_mainappid(lb_pkgname);
+ if (!package_is_enabled(mainappid)) {
+ DbgFree(mainappid);
+ DbgFree(lb_pkgname);
+ ret = LB_STATUS_ERROR_DISABLED;
+ goto out;
+ }
+ DbgFree(mainappid);
+
info = package_find(lb_pkgname);
if (!info)
info = package_create(lb_pkgname);
@@ -4523,16 +4573,16 @@ out:
static Eina_Bool lazy_pd_created_cb(void *data)
{
- (void)instance_del_data(data, "lazy,pd,open");
-
- /*!
- * After unref instance first,
- * if the instance is not destroyed, try to notify the created PD event to the client.
- */
- if (instance_unref(data)) {
- int ret;
- ret = instance_client_pd_created(data, LB_STATUS_SUCCESS);
- DbgPrint("Send PD Create event (%d)\n", ret);
+ if (!!instance_del_data(data, "lazy,pd,open")) {
+ /*!
+ * After unref instance first,
+ * if the instance is not destroyed, try to notify the created PD event to the client.
+ */
+ if (instance_unref(data)) {
+ int ret;
+ ret = instance_client_pd_created(data, LB_STATUS_SUCCESS);
+ DbgPrint("Send PD Create event (%d)\n", ret);
+ }
}
return ECORE_CALLBACK_CANCEL;
@@ -4540,11 +4590,12 @@ static Eina_Bool lazy_pd_created_cb(void *data)
static Eina_Bool lazy_pd_destroyed_cb(void *data)
{
- (void)instance_del_data(data, "lazy,pd,close");
-
- if (instance_unref(data)) {
- DbgPrint("Send PD Destroy event\n");
- instance_client_pd_destroyed(data, LB_STATUS_SUCCESS);
+ if (!!instance_del_data(data, "lazy,pd,close")) {
+ if (instance_unref(data)) {
+ int ret;
+ ret = instance_client_pd_destroyed(data, LB_STATUS_SUCCESS);
+ DbgPrint("Send PD Destroy event (%d)\n", ret);
+ }
}
return ECORE_CALLBACK_CANCEL;
@@ -4616,7 +4667,18 @@ static Eina_Bool pd_close_monitor_cb(void *data)
ret = instance_client_pd_destroyed(data, LB_STATUS_ERROR_TIMEOUT);
(void)instance_del_data(data, "pd,close,monitor");
(void)instance_unref(data);
- ErrPrint("PD Close request it not processed in %lf seconds\n", PD_REQUEST_TIMEOUT);
+ ErrPrint("PD Close request is not processed in %lf seconds (%d)\n", PD_REQUEST_TIMEOUT, ret);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool pd_resize_monitor_cb(void *data)
+{
+ int ret;
+
+ ret = instance_client_pd_destroyed(data, LB_STATUS_ERROR_TIMEOUT);
+ (void)instance_del_data(data, "pd,resize,monitor");
+ (void)instance_unref(data);
+ ErrPrint("PD Resize request is not processed in %lf seconds (%d)\n", PD_REQUEST_TIMEOUT, ret);
return ECORE_CALLBACK_CANCEL;
}
@@ -4649,9 +4711,29 @@ static struct packet *client_create_pd(pid_t pid, int handle, const struct packe
if (ret != LB_STATUS_SUCCESS)
goto out;
- if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE)
+ if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE) {
ret = LB_STATUS_ERROR_NO_SPACE;
- else if (package_pd_type(instance_package(inst)) == PD_TYPE_BUFFER) {
+ } else if (package_pd_type(instance_package(inst)) == PD_TYPE_BUFFER) {
+ lazy_pd_destroyed_cb(inst);
+
+ if (instance_get_data(inst, "pd,open,monitor")) {
+ DbgPrint("PD Open request is already processed\n");
+ ret = LB_STATUS_ERROR_ALREADY;
+ goto out;
+ }
+
+ if (instance_get_data(inst, "pd,close,monitor")) {
+ DbgPrint("PD Close request is already in process\n");
+ ret = LB_STATUS_ERROR_BUSY;
+ goto out;
+ }
+
+ if (instance_get_data(inst, "pd,resize,monitor")) {
+ DbgPrint("PD resize request is already in process\n");
+ ret = LB_STATUS_ERROR_BUSY;
+ goto out;
+ }
+
instance_slave_set_pd_pos(inst, x, y);
/*!
* \note
@@ -4692,6 +4774,9 @@ static struct packet *client_create_pd(pid_t pid, int handle, const struct packe
} else if (package_pd_type(instance_package(inst)) == PD_TYPE_SCRIPT) {
int ix;
int iy;
+
+ lazy_pd_destroyed_cb(inst);
+
/*!
* \note
* ret value should be cared but in this case,
@@ -4717,6 +4802,7 @@ static struct packet *client_create_pd(pid_t pid, int handle, const struct packe
*/
if (ret == LB_STATUS_SUCCESS) {
Ecore_Timer *timer;
+
/*!
* \note
* But the created event has to be send afte return
@@ -4784,6 +4870,7 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
int ret;
struct inst_info *inst;
const struct pkg_info *pkg;
+ Ecore_Timer *pd_monitor;
client = client_find_by_pid(pid);
if (!client) {
@@ -4804,7 +4891,7 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
goto out;
if (package_pd_type(pkg) == PD_TYPE_BUFFER) {
- Ecore_Timer *pd_monitor;
+ int resize_aborted = 0;
pd_monitor = instance_del_data(inst, "pd,open,monitor");
if (pd_monitor) {
@@ -4819,13 +4906,39 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
* Because they understand that the destroy request is successfully processed.
*/
ret = LB_STATUS_ERROR_CANCEL;
+ ret = instance_client_pd_created(inst, ret);
+ if (ret < 0)
+ ErrPrint("PD client create event: %d\n", ret);
+
+ ret = instance_client_pd_destroyed(inst, LB_STATUS_SUCCESS);
+ if (ret < 0)
+ ErrPrint("PD client destroy event: %d\n", ret);
+
+ ret = instance_signal_emit(inst, "pd,hide", instance_id(inst), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
+ if (ret < 0)
+ ErrPrint("PD close signal emit failed: %d\n", ret);
+
+ ret = instance_slave_close_pd(inst, client);
+ if (ret < 0)
+ ErrPrint("PD close request failed: %d\n", ret);
- (void)instance_client_pd_created(inst, ret);
ecore_timer_del(pd_monitor);
(void)instance_unref(inst);
goto out;
}
+ pd_monitor = instance_del_data(inst, "pd,resize,monitor");
+ if (pd_monitor) {
+ ErrPrint("PD Resize request is found. clear it [%s]\n", pkgname);
+ ecore_timer_del(pd_monitor);
+
+ inst = instance_unref(inst);
+ if (!inst)
+ goto out;
+
+ resize_aborted = 1;
+ }
+
ret = instance_signal_emit(inst, "pd,hide", instance_id(inst), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
if (ret < 0)
ErrPrint("PD close signal emit failed: %d\n", ret);
@@ -4834,12 +4947,22 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
if (ret < 0) {
ErrPrint("PD close request failed: %d\n", ret);
} else {
- pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_close_monitor_cb, instance_ref(inst));
- if (!pd_monitor) {
- (void)instance_unref(inst);
- ErrPrint("Failed to add pd close monitor\n");
+ if (resize_aborted) {
+ pd_monitor = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, instance_ref(inst));
+ if (!pd_monitor) {
+ ErrPrint("Failed to create a timer: %s\n", pkgname);
+ (void)instance_unref(inst);
+ } else {
+ (void)instance_set_data(inst, "lazy,pd,close", pd_monitor);
+ }
} else {
- (void)instance_set_data(inst, "pd,close,monitor", pd_monitor);
+ pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_close_monitor_cb, instance_ref(inst));
+ if (!pd_monitor) {
+ (void)instance_unref(inst);
+ ErrPrint("Failed to add pd close monitor\n");
+ } else {
+ (void)instance_set_data(inst, "pd,close,monitor", pd_monitor);
+ }
}
}
/*!
@@ -4850,6 +4973,8 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
* instance_client_pd_destroyed(inst);
*/
} else if (package_pd_type(pkg) == PD_TYPE_SCRIPT) {
+ lazy_pd_created_cb(inst);
+
ret = script_handler_unload(instance_pd_script(inst), 1);
if (ret < 0)
ErrPrint("Unable to unload the script: %s, %d\n", pkgname, ret);
@@ -4868,10 +4993,6 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
* Send the destroyed PD event to the client
*/
if (ret == LB_STATUS_SUCCESS) {
- Ecore_Timer *timer;
-
- inst = instance_ref(inst);
-
/*!
* \note
* 13-05-28
@@ -4879,16 +5000,12 @@ static struct packet *client_destroy_pd(pid_t pid, int handle, const struct pack
* But I just add it to the tagged-data of the instance.
* Just reserve for future-use.
*/
- timer = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, inst);
- if (!timer) {
+ pd_monitor = ecore_timer_add(DELAY_TIME, lazy_pd_destroyed_cb, instance_ref(inst));
+ if (!pd_monitor) {
ErrPrint("Failed to create a timer: %s\n", pkgname);
(void)instance_unref(inst);
- /*!
- * How can we handle this?
- */
- ret = LB_STATUS_ERROR_FAULT;
} else {
- (void)instance_set_data(inst, "lazy,pd,close", timer);
+ (void)instance_set_data(inst, "lazy,pd,close", pd_monitor);
}
}
} else {
@@ -5258,7 +5375,11 @@ static struct packet *slave_hello(pid_t pid, int handle, const struct packet *pa
DbgPrint("New slave[%s](%d) is arrived\n", slavename, pid);
- slave = slave_find_by_pid(pid);
+ slave = slave_find_by_name(slavename);
+
+ if (!slave) /* Try again to find a slave using pid */
+ slave = slave_find_by_pid(pid);
+
if (!slave) {
if (DEBUG_MODE) {
char pkgname[pathconf("/", _PC_PATH_MAX)];
@@ -5294,9 +5415,22 @@ static struct packet *slave_hello(pid_t pid, int handle, const struct packet *pa
slave_set_pid(slave, pid);
DbgPrint("Provider is forcely activated, pkgname(%s), abi(%s), slavename(%s)\n", pkgname, abi, slavename);
} else {
- ErrPrint("Slave[%d] is not exists\n", pid);
+ ErrPrint("Slave[%d, %s] is not exists\n", pid, slavename);
goto out;
}
+ } else {
+ if (slave_pid(slave) != pid) {
+ if (slave_pid(slave) > 0) {
+ CRITICAL_LOG("Slave(%s) is already assigned to %d\n", slave_name(slave), slave_pid(slave));
+ if (pid > 0) {
+ ret = aul_terminate_pid(pid);
+ CRITICAL_LOG("Terminate %d (ret: %d)\n", pid, ret);
+ }
+ goto out;
+ }
+ CRITICAL_LOG("PID of slave(%s) is updated (%d -> %d)\n", slave_name(slave), slave_pid(slave), pid);
+ slave_set_pid(slave, pid);
+ }
}
/*!
@@ -5362,6 +5496,7 @@ static struct packet *slave_faulted(pid_t pid, int handle, const struct packet *
} else if (instance_state(inst) == INST_DESTROYED) {
ErrPrint("Instance(%s) is already destroyed\n", id);
} else {
+ //clear_pd_monitor(inst);
ret = instance_destroy(inst);
}
@@ -5792,8 +5927,10 @@ static struct packet *slave_deleted(pid_t pid, int handle, const struct packet *
}
ret = validate_request(pkgname, id, &inst, NULL);
- if (ret == LB_STATUS_SUCCESS)
+ if (ret == LB_STATUS_SUCCESS) {
+ //clear_pd_monitor(inst);
ret = instance_destroyed(inst);
+ }
out:
return NULL;
@@ -5833,7 +5970,7 @@ static struct packet *slave_acquire_buffer(pid_t pid, int handle, const struct p
}
if (util_free_space(IMAGE_PATH) < MINIMUM_SPACE) {
- DbgPrint("No space\n");
+ ErrPrint("Not enough space\n");
ret = LB_STATUS_ERROR_NO_SPACE;
id = "";
goto out;
@@ -5886,10 +6023,16 @@ static struct packet *slave_acquire_buffer(pid_t pid, int handle, const struct p
} else if (target == TYPE_PD && package_pd_type(pkg) == PD_TYPE_BUFFER) {
struct buffer_info *info;
Ecore_Timer *pd_monitor;
+ int is_resize;
+ is_resize = 0;
pd_monitor = instance_del_data(inst, "pd,open,monitor");
- if (!pd_monitor)
- goto out;
+ if (!pd_monitor) {
+ pd_monitor = instance_del_data(inst, "pd,resize,monitor");
+ is_resize = !!pd_monitor;
+ if (!is_resize)
+ goto out;
+ }
ecore_timer_del(pd_monitor);
inst = instance_unref(inst);
@@ -5931,7 +6074,8 @@ static struct packet *slave_acquire_buffer(pid_t pid, int handle, const struct p
/*!
* Send the PD created event to the client
*/
- instance_client_pd_created(inst, ret);
+ if (!is_resize)
+ instance_client_pd_created(inst, ret);
}
out:
@@ -6092,6 +6236,32 @@ static struct packet *slave_release_buffer(pid_t pid, int handle, const struct p
* by pd.need_to_send_close_event flag.
* which will be checked by instance_client_pd_destroyed function.
*/
+
+ /*!
+ * \note
+ * provider can try to resize the buffer size.
+ * in that case, it will release the buffer first.
+ * Then even though the client doesn't request to close the PD,
+ * the provider can release it.
+ * If we send the close event to the client,
+ * The client will not able to allocate PD again.
+ * In this case, add the pd,monitor again. from here.
+ * to wait the re-allocate buffer.
+ * If the client doesn't request buffer reallocation,
+ * Treat it as a fault. and close the PD.
+ */
+ info = instance_pd_buffer(inst);
+ ret = buffer_handler_unload(info);
+
+ if (ret == LB_STATUS_SUCCESS) {
+ pd_monitor = ecore_timer_add(PD_REQUEST_TIMEOUT, pd_resize_monitor_cb, instance_ref(inst));
+ if (!pd_monitor) {
+ (void)instance_unref(inst);
+ ErrPrint("Failed to create a timer for PD Open monitor\n");
+ } else {
+ (void)instance_set_data(inst, "pd,resize,monitor", pd_monitor);
+ }
+ }
} else {
ecore_timer_del(pd_monitor);
inst = instance_unref(inst);
@@ -6100,16 +6270,17 @@ static struct packet *slave_release_buffer(pid_t pid, int handle, const struct p
ret = LB_STATUS_ERROR_FAULT;
goto out;
}
- }
- info = instance_pd_buffer(inst);
- ret = buffer_handler_unload(info);
+ info = instance_pd_buffer(inst);
+ ret = buffer_handler_unload(info);
+
+ /*!
+ * \note
+ * Send the PD destroyed event to the client
+ */
+ instance_client_pd_destroyed(inst, ret);
+ }
- /*!
- * \note
- * Send the PD destroyed event to the client
- */
- instance_client_pd_destroyed(inst, ret);
}
out:
@@ -6493,7 +6664,8 @@ static struct packet *liveinfo_pkg_ctrl(pid_t pid, int handle, const struct pack
if (!inst) {
fprintf(fp, "%d\n", ENOENT);
} else {
- instance_destroy(inst);
+ //clear_pd_monitor(inst);
+ (void)instance_destroy(inst);
fprintf(fp, "%d\n", 0);
}
}
diff --git a/src/service_common.c b/src/service_common.c
index 8b5405f..d6d4007 100644
--- a/src/service_common.c
+++ b/src/service_common.c
@@ -90,6 +90,7 @@ struct tcb { /* Thread controll block */
pthread_t thid; /*!< Thread Id */
int fd; /*!< Connection handle */
enum tcb_type type;
+ int ctrl_pipe[PIPE_MAX];
};
/*!
@@ -109,6 +110,7 @@ static void *client_packet_pump_main(void *data)
int recv_offset;
int pid;
int ret;
+ int fd;
char evt_ch = EVT_CH;
enum {
RECV_INIT,
@@ -128,7 +130,9 @@ static void *client_packet_pump_main(void *data)
while (ret == 0) {
FD_ZERO(&set);
FD_SET(tcb->fd, &set);
- ret = select(tcb->fd + 1, &set, NULL, NULL, NULL);
+ FD_SET(tcb->ctrl_pipe[PIPE_READ], &set);
+ fd = tcb->fd > tcb->ctrl_pipe[PIPE_READ] ? tcb->fd : tcb->ctrl_pipe[PIPE_READ];
+ ret = select(fd + 1, &set, NULL, NULL, NULL);
if (ret < 0) {
ret = -errno;
if (errno == EINTR) {
@@ -148,6 +152,14 @@ static void *client_packet_pump_main(void *data)
break;
}
+ if (FD_ISSET(tcb->ctrl_pipe[PIPE_READ], &set)) {
+ DbgPrint("Thread is canceled\n");
+ ret = -ECANCELED;
+ free(ptr);
+ ptr = NULL;
+ break;
+ }
+
if (!FD_ISSET(tcb->fd, &set)) {
ErrPrint("Unexpected handler is toggled\n");
ret = -EINVAL;
@@ -321,6 +333,12 @@ static inline struct tcb *tcb_create(struct service_context *svc_ctx, int fd)
return NULL;
}
+ if (pipe2(tcb->ctrl_pipe, O_NONBLOCK | O_CLOEXEC) < 0) {
+ ErrPrint("pipe2: %s\n", strerror(errno));
+ free(tcb);
+ return NULL;
+ }
+
tcb->fd = fd;
tcb->svc_ctx = svc_ctx;
tcb->type = TCB_CLIENT_TYPE_APP;
@@ -329,6 +347,7 @@ static inline struct tcb *tcb_create(struct service_context *svc_ctx, int fd)
status = pthread_create(&tcb->thid, NULL, client_packet_pump_main, tcb);
if (status != 0) {
ErrPrint("Unable to create a new thread: %s\n", strerror(status));
+ CLOSE_PIPE(tcb->ctrl_pipe);
free(tcb);
return NULL;
}
@@ -346,6 +365,7 @@ static inline void tcb_teminate_all(struct service_context *svc_ctx)
struct tcb *tcb;
void *ret;
int status;
+ char ch = EVT_END_CH;
/*!
* We don't need to make critical section on here.
@@ -356,7 +376,8 @@ static inline void tcb_teminate_all(struct service_context *svc_ctx)
/*!
* ASSERT(tcb->fd >= 0);
*/
- secure_socket_destroy_handle(tcb->fd);
+ if (write(tcb->ctrl_pipe[PIPE_WRITE], &ch, sizeof(ch)) != sizeof(ch))
+ ErrPrint("write: %s\n", strerror(errno));
status = pthread_join(tcb->thid, &ret);
if (status != 0)
@@ -364,6 +385,9 @@ static inline void tcb_teminate_all(struct service_context *svc_ctx)
else
DbgPrint("Thread returns: %d\n", (int)ret);
+ secure_socket_destroy_handle(tcb->fd);
+
+ CLOSE_PIPE(tcb->ctrl_pipe);
free(tcb);
}
}
@@ -376,13 +400,15 @@ static inline void tcb_destroy(struct service_context *svc_ctx, struct tcb *tcb)
{
void *ret;
int status;
+ char ch = EVT_END_CH;
svc_ctx->tcb_list = eina_list_remove(svc_ctx->tcb_list, tcb);
/*!
* ASSERT(tcb->fd >= 0);
* Close the connection, and then collecting the return value of thread
*/
- secure_socket_destroy_handle(tcb->fd);
+ if (write(tcb->ctrl_pipe[PIPE_WRITE], &ch, sizeof(ch)) != sizeof(ch))
+ ErrPrint("write: %s\n", strerror(errno));
status = pthread_join(tcb->thid, &ret);
if (status != 0)
@@ -390,6 +416,9 @@ static inline void tcb_destroy(struct service_context *svc_ctx, struct tcb *tcb)
else
DbgPrint("Thread returns: %d\n", (int)ret);
+ secure_socket_destroy_handle(tcb->fd);
+
+ CLOSE_PIPE(tcb->ctrl_pipe);
free(tcb);
}
@@ -478,6 +507,7 @@ static void *server_main(void *data)
{
struct service_context *svc_ctx = data;
fd_set set;
+ fd_set except_set;
int ret;
int client_fd;
struct tcb *tcb;
@@ -488,8 +518,9 @@ static void *server_main(void *data)
DbgPrint("Server thread is activated\n");
while (1) {
fd = update_fdset(svc_ctx, &set);
+ memcpy(&except_set, &set, sizeof(set));
- ret = select(fd, &set, NULL, NULL, NULL);
+ ret = select(fd, &set, NULL, &except_set, NULL);
if (ret < 0) {
ret = -errno;
if (errno == EINTR) {
@@ -526,6 +557,12 @@ static void *server_main(void *data)
break;
}
+ if (!tcb) {
+ ErrPrint("Terminate service thread\n");
+ ret = -ECANCELED;
+ break;
+ }
+
/*!
* \note
* Invoke the service thread main, to notify the termination of a TCB
@@ -551,17 +588,19 @@ static void *server_main(void *data)
svc_ctx->packet_list = eina_list_remove(svc_ctx->packet_list, packet_info);
CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
- /*!
- * \CRITICAL
- * What happens if the client thread is terminated, so the packet_info->tcb is deleted
- * while processing svc_ctx->service_thread_main?
- */
- 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);
+ if (packet_info) {
+ /*!
+ * \CRITICAL
+ * What happens if the client thread is terminated, so the packet_info->tcb is deleted
+ * while processing svc_ctx->service_thread_main?
+ */
+ 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);
+ }
}
processing_timer_event(svc_ctx, &set);
@@ -671,6 +710,13 @@ HAPI struct service_context *service_common_create(const char *addr, int (*servi
return NULL;
}
+ /*!
+ * \note
+ * To give a chance to run for server thread.
+ */
+ DbgPrint("Yield\n");
+ pthread_yield();
+
return svc_ctx;
}
@@ -680,7 +726,7 @@ HAPI struct service_context *service_common_create(const char *addr, int (*servi
*/
HAPI int service_common_destroy(struct service_context *svc_ctx)
{
- int status;
+ int status = 0;
void *ret;
if (!svc_ctx)
@@ -690,7 +736,8 @@ HAPI int service_common_destroy(struct service_context *svc_ctx)
* \note
* Terminate server thread
*/
- secure_socket_destroy_handle(svc_ctx->fd);
+ if (write(svc_ctx->tcb_pipe[PIPE_WRITE], &status, sizeof(status)) != sizeof(status))
+ ErrPrint("Failed to write: %s\n", strerror(errno));
status = pthread_join(svc_ctx->server_thid, &ret);
if (status != 0)
@@ -698,6 +745,8 @@ HAPI int service_common_destroy(struct service_context *svc_ctx)
else
DbgPrint("Thread returns: %d\n", (int)ret);
+ secure_socket_destroy_handle(svc_ctx->fd);
+
status = pthread_mutex_destroy(&svc_ctx->packet_list_lock);
if (status != 0)
ErrPrint("Unable to destroy a mutex: %s\n", strerror(status));
@@ -839,7 +888,8 @@ HAPI struct service_event_item *service_common_add_timer(struct service_context
if (timerfd_settime(item->info.timer.fd, 0, &spec, NULL) < 0) {
ErrPrint("Error: %s\n", strerror(errno));
- close(item->info.timer.fd);
+ if (close(item->info.timer.fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
free(item);
return NULL;
}
@@ -864,9 +914,15 @@ HAPI int service_common_del_timer(struct service_context *svc_ctx, struct servic
svc_ctx->event_list = eina_list_remove(svc_ctx->event_list, item);
- close(item->info.timer.fd);
+ if (close(item->info.timer.fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
free(item);
return 0;
}
+HAPI int service_common_fd(struct service_context *ctx)
+{
+ return ctx->fd;
+}
+
/* End of a file */
diff --git a/src/setting.c b/src/setting.c
index e7e5379..47c41c8 100644
--- a/src/setting.c
+++ b/src/setting.c
@@ -30,6 +30,8 @@
#include <Ecore.h>
#include <Eina.h>
+#include <livebox-service.h>
+
#include "client_life.h"
#include "setting.h"
#include "util.h"
@@ -38,6 +40,8 @@
#include "critical_log.h"
#include "xmonitor.h"
#include "conf.h"
+#include "package.h"
+#include "instance.h"
int errno;
@@ -80,8 +84,8 @@ static void power_off_cb(keynode_t *node, void *user_data)
ErrPrint("stop.provider [%s]\n", strerror(errno));
vconf_set_bool(VCONFKEY_MASTER_STARTED, 0);
- exit(0);
- //ecore_main_loop_quit();
+ //exit(0);
+ ecore_main_loop_quit();
} else {
ErrPrint("Unknown power state: %d\n", val);
}
@@ -112,7 +116,7 @@ static void region_changed_cb(keynode_t *node, void *user_data)
if (r == NULL)
ErrPrint("Failed to change region\n");
- free(region);
+ DbgFree(region);
}
static void lang_changed_cb(keynode_t *node, void *user_data)
@@ -132,7 +136,70 @@ static void lang_changed_cb(keynode_t *node, void *user_data)
ErrPrint("Failed to change locale\n");
DbgPrint("Locale: %s\n", setlocale(LC_ALL, NULL));
- free(lang);
+ DbgFree(lang);
+}
+
+static void ail_info_cb(keynode_t *node, void *user_data)
+{
+ Eina_List *inst_list;
+ Eina_List *pkg_list;
+ struct inst_info *inst;
+ Eina_List *l;
+ Eina_List *n;
+ Eina_List *j;
+ struct pkg_info *info;
+ char *event;
+ char *appid;
+ char *pkgname;
+ int len;
+ int enabled;
+
+ event = vconf_get_str(VCONFKEY_AIL_INFO_STATE);
+ if (!event)
+ return;
+
+ len = strlen("update:");
+ if (!strncasecmp(event, "update:", len))
+ goto out;
+
+ appid = event + len;
+ DbgPrint("AppId: [%s]\n", appid);
+
+ enabled = package_is_enabled(appid);
+
+ DbgPrint("AppId: %s, %d\n", appid, enabled);
+ if (enabled != 0) {
+ /*
+ * \note
+ * reload?
+ */
+ goto out;
+ }
+
+ len = strlen(appid);
+
+ pkg_list = (Eina_List *)package_list();
+ EINA_LIST_FOREACH(pkg_list, l, info) {
+ inst_list = NULL;
+ pkgname = livebox_service_mainappid(package_name(info));
+ if (!pkgname)
+ continue;
+
+ if (strcmp(appid, pkgname)) {
+ DbgFree(pkgname);
+ continue;
+ }
+ DbgPrint("Package disabled: %s (%s)\n", pkgname, appid);
+ DbgFree(pkgname);
+
+ inst_list = package_instance_list(info);
+ EINA_LIST_FOREACH_SAFE(inst_list, j, n, inst) {
+ instance_destroy(inst);
+ }
+ }
+
+out:
+ DbgFree(event);
}
HAPI int setting_init(void)
@@ -155,6 +222,10 @@ HAPI int setting_init(void)
if (ret < 0)
ErrPrint("Failed to add vconf for region change: %d\n", ret);
+ ret = vconf_notify_key_changed(VCONFKEY_AIL_INFO_STATE, ail_info_cb, NULL);
+ if (ret < 0)
+ ErrPrint("Failed to add vconf for ail info state: %d\n", ret);
+
lang_changed_cb(NULL, NULL);
region_changed_cb(NULL, NULL);
return ret;
@@ -180,6 +251,10 @@ HAPI int setting_fini(void)
if (ret < 0)
ErrPrint("Failed to ignore vconf key (%d)\n", ret);
+ ret = vconf_ignore_key_changed(VCONFKEY_AIL_INFO_STATE, ail_info_cb);
+ if (ret < 0)
+ ErrPrint("Failed to ignore vconf key (%d)\n", ret);
+
return ret;
}
diff --git a/src/shortcut_service.c b/src/shortcut_service.c
index a2f74af..690c08b 100644
--- a/src/shortcut_service.c
+++ b/src/shortcut_service.c
@@ -22,14 +22,15 @@
#include <packet.h>
#include <Eina.h>
+#include <sys/smack.h>
+
+#include <security-server.h>
#include "service_common.h"
#include "debug.h"
#include "util.h"
#include "conf.h"
-#define SHORTCUT_ADDR "/tmp/.shortcut.service"
-
static struct info {
Eina_List *context_list;
struct service_context *svc_ctx;
@@ -162,12 +163,30 @@ HAPI int shortcut_service_init(void)
return LB_STATUS_ERROR_ALREADY;
}
- s_info.svc_ctx = service_common_create(SHORTCUT_ADDR, service_thread_main, NULL);
+ s_info.svc_ctx = service_common_create(SHORTCUT_SOCKET, service_thread_main, NULL);
if (!s_info.svc_ctx) {
ErrPrint("Unable to activate service thread\n");
return LB_STATUS_ERROR_FAULT;
}
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), SHORTCUT_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), SHORTCUT_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
DbgPrint("Successfully initiated\n");
return LB_STATUS_SUCCESS;
}
@@ -178,6 +197,7 @@ HAPI int shortcut_service_fini(void)
return LB_STATUS_ERROR_INVALID;
service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
DbgPrint("Successfully Finalized\n");
return LB_STATUS_SUCCESS;
}
diff --git a/src/slave_life.c b/src/slave_life.c
index fba87fc..8d36a27 100644
--- a/src/slave_life.c
+++ b/src/slave_life.c
@@ -33,6 +33,7 @@
#include <packet.h>
#include <livebox-errno.h>
+#include "critical_log.h"
#include "slave_life.h"
#include "slave_rpc.h"
#include "client_life.h"
@@ -390,31 +391,36 @@ static Eina_Bool activate_timer_cb(void *data)
ErrPrint("Terminate failed, pid %d (reason: %d)\n", slave_pid(slave), ret);
}
- ErrPrint("Slave is not activated in %lf sec (slave: %s)\n", SLAVE_ACTIVATE_TIME, slave_name(slave));
+ CRITICAL_LOG("Slave is not activated in %lf sec (slave: %s)\n", SLAVE_ACTIVATE_TIME, slave_name(slave));
slave = slave_deactivated(slave);
- DbgPrint("Slave: %p\n", slave);
return ECORE_CALLBACK_CANCEL;
}
HAPI int slave_activate(struct slave_node *slave)
{
-
/*!
* \note
- * This check code can replace the slave->state check code
+ * This check code can be replaced with the slave->state check code
* If the slave data has the PID, it means, it is activated
* Even if it is in the termiating sequence, it will have the PID
* before terminated at last.
* So we can use this simple code for checking the slave's last state.
* about it is alive? or not.
*/
- if (slave_pid(slave) != (pid_t)-1)
+ if (slave_pid(slave) != (pid_t)-1) {
+ if (slave_state(slave) == SLAVE_REQUEST_TO_TERMINATE)
+ slave_set_reactivation(slave, 1);
return LB_STATUS_ERROR_ALREADY;
+ } else if (slave_state(slave) == SLAVE_REQUEST_TO_LAUNCH) {
+ DbgPrint("Slave is already launched: but the AUL is timed out\n");
+ return LB_STATUS_ERROR_ALREADY;
+ }
if (DEBUG_MODE) {
DbgPrint("Debug Mode enabled. name[%s] secured[%d] abi[%s]\n", slave_name(slave), slave->secured, slave->abi);
} else {
bundle *param;
+
param = bundle_create();
if (!param) {
ErrPrint("Failed to create a bundle\n");
@@ -430,9 +436,15 @@ HAPI int slave_activate(struct slave_node *slave)
bundle_free(param);
if (slave->pid < 0) {
- ErrPrint("Failed to launch a new slave %s (%d)\n", slave_name(slave), slave->pid);
- slave->pid = (pid_t)-1;
- return LB_STATUS_ERROR_FAULT;
+ 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;
+ return LB_STATUS_ERROR_FAULT;
+ } else {
+ ErrPrint("But waiting \"hello\"\n");
+ slave->pid = (pid_t)-1;
+ }
}
DbgPrint("Slave %s is launched with %d as %s\n", slave_pkgname(slave), slave->pid, slave_name(slave));
@@ -1302,4 +1314,38 @@ HAPI void slave_set_network(struct slave_node *slave, int network)
slave->network = network;
}
+HAPI int slave_deactivate_all(int reactivate, int reactivate_instances)
+{
+ Eina_List *l;
+ Eina_List *n;
+ struct slave_node *slave;
+ int cnt = 0;
+
+ EINA_LIST_FOREACH_SAFE(s_info.slave_list, l, n, slave) {
+ slave_set_reactivate_instances(slave, reactivate_instances);
+ slave_set_reactivation(slave, reactivate);
+
+ if (!slave_deactivate(slave))
+ s_info.slave_list = eina_list_remove(s_info.slave_list, slave);
+
+ cnt++;
+ }
+
+ return cnt;
+}
+
+HAPI int slave_activate_all(void)
+{
+ Eina_List *l;
+ struct slave_node *slave;
+ int cnt = 0;
+
+ EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
+ slave_activate(slave);
+ cnt++;
+ }
+
+ return cnt;
+}
+
/* End of a file */
diff --git a/src/slave_rpc.c b/src/slave_rpc.c
index faeb94b..0e66261 100644
--- a/src/slave_rpc.c
+++ b/src/slave_rpc.c
@@ -123,7 +123,7 @@ static int slave_async_cb(pid_t pid, int handle, const struct packet *packet, vo
struct command *command = data;
if (!command) {
- ErrPrint("Packet is NIL\n");
+ ErrPrint("Command is NIL\n");
return LB_STATUS_SUCCESS;
}
@@ -135,7 +135,6 @@ static int slave_async_cb(pid_t pid, int handle, const struct packet *packet, vo
ErrPrint("Slave is not activated (accidently dead)\n");
if (command->ret_cb)
command->ret_cb(command->slave, packet, command->cbdata);
-
goto out;
}
@@ -144,7 +143,14 @@ static int slave_async_cb(pid_t pid, int handle, const struct packet *packet, vo
if (command->ret_cb)
command->ret_cb(command->slave, packet, command->cbdata);
+ /*
+ * \NOTE
+ * Slave will be deactivated from dead monitor if it lost its connections.
+ * So we don't need to care it again from here.
+
command->slave = slave_deactivated_by_fault(command->slave);
+
+ */
goto out;
}
diff --git a/src/utility_service.c b/src/utility_service.c
index 651e284..0b01608 100644
--- a/src/utility_service.c
+++ b/src/utility_service.c
@@ -23,15 +23,22 @@
#include <livebox-errno.h>
#include <packet.h>
+#include <sys/smack.h>
+
+#include "critical_log.h"
#include "service_common.h"
#include "utility_service.h"
#include "debug.h"
#include "util.h"
#include "conf.h"
-#define UTILITY_ADDR "/tmp/.utility.service"
+#ifndef SVC_PKG
#define SVC_PKG "org.tizen.data-provider-slave.icon"
+#endif
+
+#ifndef LAUNCH_TIMEOUT
#define LAUNCH_TIMEOUT 10.0f
+#endif
static struct info {
Eina_List *pending_list;
@@ -39,18 +46,20 @@ static struct info {
struct service_context *svc_ctx;
struct tcb *svc_daemon;
- pid_t svc_pid;
+ int svc_daemon_is_launched;
struct service_event_item *launch_timer;
+ struct service_event_item *delay_launcher;
} s_info = {
.pending_list = NULL,
.context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
.svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
.svc_daemon = NULL,
- .svc_pid = -1,
+ .svc_daemon_is_launched = 0,
.launch_timer = NULL,
+ .delay_launcher = NULL,
};
struct pending_item {
@@ -63,6 +72,8 @@ struct context {
double seq;
};
+static int lazy_launcher_cb(struct service_context *svc_ctx, void *data);
+
static inline int put_reply_tcb(struct tcb *tcb, double seq)
{
struct context *ctx;
@@ -172,9 +183,51 @@ static int launch_timeout_cb(struct service_context *svc_ctx, void *data)
}
s_info.launch_timer = NULL;
+ s_info.svc_daemon_is_launched = 0;
return -ECANCELED; /* Delete this timer */
}
+static inline 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) {
+ /* Need time to launch app again */
+ ErrPrint("Terminating now, try to launch this after few sec later\n");
+ 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;
+ }
+
+ 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;
+ return -ECANCELED;
+}
+
static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
{
struct packet *reply;
@@ -186,7 +239,7 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat
if (tcb == s_info.svc_daemon) {
s_info.svc_daemon = NULL;
- s_info.svc_pid = -1;
+ s_info.svc_daemon_is_launched = 0;
}
return 0;
@@ -200,20 +253,13 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat
switch (packet_type(packet)) {
case PACKET_REQ:
- if (s_info.svc_pid < 0) {
- s_info.svc_pid = aul_launch_app(SVC_PKG, NULL);
- if (s_info.svc_pid > 0) {
- s_info.launch_timer = service_common_add_timer(tcb_svc_ctx(tcb), LAUNCH_TIMEOUT, launch_timeout_cb, NULL);
- if (!s_info.launch_timer)
- ErrPrint("Unable to create launch timer\n");
- }
+ if (!s_info.svc_daemon_is_launched) {
+ ret = launch_svc(tcb_svc_ctx(tcb));
+ if (ret != LB_STATUS_SUCCESS)
+ goto reply_out;
}
- if (s_info.svc_pid < 0) {
- ErrPrint("Failed to launch an app: %s(%d)\n", SVC_PKG, s_info.svc_pid);
- ret = LB_STATUS_ERROR_FAULT;
- goto reply_out;
- } else if (!s_info.svc_daemon) {
+ if (!s_info.svc_daemon) {
ret = put_pended_request(tcb, packet);
if (ret < 0)
goto reply_out;
@@ -228,6 +274,11 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat
break;
case PACKET_REQ_NOACK:
if (!strcmp(cmd, "service_register")) {
+ if (!s_info.svc_daemon_is_launched) {
+ ErrPrint("Service daemon is not launched. but something tries to register a service\n");
+ return LB_STATUS_ERROR_INVALID;
+ }
+
if (s_info.svc_daemon) {
ErrPrint("Service daemon is already prepared\n");
return LB_STATUS_ERROR_INVALID;
@@ -275,12 +326,30 @@ int utility_service_init(void)
return LB_STATUS_ERROR_ALREADY;
}
- s_info.svc_ctx = service_common_create(UTILITY_ADDR, service_thread_main, NULL);
+ s_info.svc_ctx = service_common_create(UTILITY_SOCKET, service_thread_main, NULL);
if (!s_info.svc_ctx) {
ErrPrint("Unable to activate service thread\n");
return LB_STATUS_ERROR_FAULT;
}
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), UTILITY_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
+ if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), UTILITY_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
+ if (errno != EOPNOTSUPP) {
+ ErrPrint("Unable to set SMACK label(%d)\n", errno);
+ service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
DbgPrint("Successfully initiated\n");
return LB_STATUS_SUCCESS;
}
@@ -291,6 +360,7 @@ int utility_service_fini(void)
return LB_STATUS_ERROR_INVALID;
service_common_destroy(s_info.svc_ctx);
+ s_info.svc_ctx = NULL;
DbgPrint("Successfully Finalized\n");
return LB_STATUS_SUCCESS;
}
diff --git a/src/xmonitor.c b/src/xmonitor.c
index e687959..b56966e 100644
--- a/src/xmonitor.c
+++ b/src/xmonitor.c
@@ -74,10 +74,12 @@ static inline void touch_paused_file(void)
{
int fd;
fd = creat(PAUSED_FILE, 0644);
- if (fd >= 0)
- close(fd);
- else
+ if (fd >= 0) {
+ if (close(fd) < 0)
+ ErrPrint("close: %s\n", strerror(errno));
+ } else {
ErrPrint("Create .live.paused: %s\n", strerror(errno));
+ }
}
static inline void remove_paused_file(void)