summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHwankyu Jhun <h.jhun@samsung.com>2016-10-24 17:58:15 +0900
committerHwankyu Jhun <h.jhun@samsung.com>2016-10-31 16:37:16 +0900
commit49c2e62468d47e7b30877f24cf20a3df226687f2 (patch)
tree249c336b474e0a707945cc38a1f007759f8a4405
parentd8df094776e77842517c62f3eb2be959061d2151 (diff)
downloadlaunchpad-49c2e62468d47e7b30877f24cf20a3df226687f2.tar.gz
launchpad-49c2e62468d47e7b30877f24cf20a3df226687f2.tar.bz2
launchpad-49c2e62468d47e7b30877f24cf20a3df226687f2.zip
- Rename the header file and functions - Remove inline definitions - Add fallback code about sending dbus signal Change-Id: Ibdb31370fa1c434b762d010ba690ab5cd81f6981 Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
-rwxr-xr-xCMakeLists.txt1
-rw-r--r--inc/launchpad_signal.h31
-rwxr-xr-xsrc/launchpad.c18
-rw-r--r--src/launchpad_signal.c (renamed from inc/sigchild.h)163
4 files changed, 183 insertions, 30 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2c0aa51..561895b 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -101,6 +101,7 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES
src/launcher_info.c
src/debugger_info.c
src/launchpad_debug.c
+ src/launchpad_signal.c
)
ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES})
diff --git a/inc/launchpad_signal.h b/inc/launchpad_signal.h
new file mode 100644
index 0000000..a2dbccb
--- /dev/null
+++ b/inc/launchpad_signal.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+#ifndef __LAUNCHPAD_SIGNAL_H__
+#define __LAUNCHPAD_SIGNAL_H__
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/signalfd.h>
+
+int _signal_send_app_launch_signal(int launch_pid, const char *app_id);
+void _signal_process_sigchld(struct signalfd_siginfo *info);
+int _signal_get_sigchld_fd(void);
+int _signal_unblock_sigchld(void);
+int _signal_init(void);
+void _signal_fini(void);
+
+#endif /* __LAUNCHPAD_SIGNAL_H__ */
diff --git a/src/launchpad.c b/src/launchpad.c
index 09e0431..55c6288 100755
--- a/src/launchpad.c
+++ b/src/launchpad.c
@@ -37,7 +37,7 @@
#include "perf.h"
#include "launchpad_common.h"
-#include "sigchild.h"
+#include "launchpad_signal.h"
#include "key.h"
#include "launchpad.h"
#include "loader_info.h"
@@ -383,8 +383,8 @@ static int __exec_loader_process(void *arg)
{
char **argv = arg;
- __signal_unblock_sigchld();
- __signal_fini();
+ _signal_unblock_sigchld();
+ _signal_fini();
_close_all_fds();
@@ -734,8 +734,8 @@ static int __exec_app_process(void *arg)
if (bundle_get_type(launch_arg->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE)
_debug_prepare_debugger(launch_arg->kb);
- __signal_unblock_sigchld();
- __signal_fini();
+ _signal_unblock_sigchld();
+ _signal_fini();
_delete_sock_path(getpid(), getuid());
@@ -793,7 +793,7 @@ static int __launchpad_pre_init(int argc, char **argv)
int fd;
/* signal init*/
- __signal_init();
+ _signal_init();
/* create launchpad sock */
fd = __create_sock_activation();
@@ -1002,7 +1002,7 @@ static gboolean __handle_sigchild(gpointer data)
if (s != sizeof(struct signalfd_siginfo))
break;
- __launchpad_process_sigchld(&siginfo);
+ _signal_process_sigchld(&siginfo);
cpc = __find_slot_from_pid(siginfo.ssi_pid);
if (cpc != NULL) {
cpc->prepared = false;
@@ -1376,7 +1376,7 @@ end:
close(clifd);
if (pid > 0)
- __send_app_launch_signal_dbus(pid, menu_info->appid);
+ _signal_send_app_launch_signal(pid, menu_info->appid);
if (menu_info != NULL)
_appinfo_free(menu_info);
@@ -1507,7 +1507,7 @@ static int __init_sigchild_fd(void)
int fd = -1;
guint pollfd;
- fd = __signal_get_sigchld_fd();
+ fd = _signal_get_sigchld_fd();
if (fd < 0) {
_E("failed to get sigchld fd");
return -1;
diff --git a/inc/sigchild.h b/src/launchpad_signal.c
index aaad0e5..e802ca4 100644
--- a/inc/sigchild.h
+++ b/src/launchpad_signal.c
@@ -14,23 +14,117 @@
* limitations under the License.
*/
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/signalfd.h>
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
#include <dirent.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <gio/gio.h>
+#include <glib.h>
#include "launchpad_common.h"
+#include "launchpad_signal.h"
#define AUL_DBUS_PATH "/aul/dbus_handler"
#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
#define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
#define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
+#define PENDING_SIGNAL_INTERVAL 1000
+
+enum signal_e {
+ APP_DEAD,
+ APP_LAUNCH,
+};
+
+struct pending_signal {
+ char *appid;
+ int pid;
+ int signal;
+};
static GDBusConnection *bus;
static sigset_t oldmask;
+static GList *pending_signal_list;
+static guint timeout_handle;
+
+static int __send_app_dead_signal(int dead_pid);
+static int __send_app_launch_signal(int launch_pid, const char *app_id);
+
+static struct pending_signal *__create_pending_signal(const char *appid,
+ const int pid, const int signal)
+{
+ struct pending_signal *handle;
+
+ handle = (struct pending_signal *)calloc(1,
+ sizeof(struct pending_signal));
+ if (handle == NULL) {
+ _E("out of memory");
+ return NULL;
+ }
+
+ if (appid) {
+ handle->appid = strdup(appid);
+ if (handle->appid == NULL) {
+ _E("out of memory");
+ free(handle);
+ return NULL;
+ }
+ }
+
+ handle->pid = pid;
+ handle->signal = signal;
+
+ return handle;
+}
+
+static void __destroy_pending_signal(struct pending_signal *handle)
+{
+ if (handle == NULL)
+ return;
+
+ if (handle->appid)
+ free(handle->appid);
+ free(handle);
+}
+
+static gboolean __flush_pending_signal(gpointer data)
+{
+ struct pending_signal *handle;
+ GList *iter;
+ int ret;
+
+ if (pending_signal_list == NULL) {
+ timeout_handle = 0;
+ return FALSE;
+ }
-static inline void __socket_garbage_collector(void)
+ iter = g_list_first(pending_signal_list);
+ while (iter) {
+ handle = (struct pending_signal *)iter->data;
+ iter = g_list_next(iter);
+ if (handle) {
+ if (handle->signal == APP_DEAD) {
+ ret = __send_app_dead_signal(handle->pid);
+ } else {
+ ret = __send_app_launch_signal(handle->pid,
+ handle->appid);
+ }
+ if (ret < 0)
+ return TRUE;
+
+ pending_signal_list = g_list_remove(pending_signal_list,
+ handle);
+ __destroy_pending_signal(handle);
+ }
+ }
+
+ timeout_handle = 0;
+
+ return FALSE;
+}
+
+static void __socket_garbage_collector(void)
{
DIR *dp;
struct dirent *dentry;
@@ -54,7 +148,7 @@ static inline void __socket_garbage_collector(void)
closedir(dp);
}
-static inline int __send_app_dead_signal_dbus(int dead_pid)
+static int __send_app_dead_signal(int dead_pid)
{
GError *err = NULL;
@@ -94,8 +188,7 @@ static inline int __send_app_dead_signal_dbus(int dead_pid)
return 0;
}
-static inline int __send_app_launch_signal_dbus(int launch_pid,
- const char *app_id)
+static int __send_app_launch_signal(int launch_pid, const char *app_id)
{
GError *err = NULL;
GVariant *param;
@@ -136,21 +229,53 @@ static inline int __send_app_launch_signal_dbus(int launch_pid,
return 0;
}
+int _signal_send_app_launch_signal(int launch_pid, const char *app_id)
+{
+ int ret;
+ struct pending_signal *handle;
+
+ ret = __send_app_launch_signal(launch_pid, app_id);
+ if (ret < 0) {
+ handle = __create_pending_signal(app_id, launch_pid,
+ APP_LAUNCH);
+ pending_signal_list = g_list_append(pending_signal_list,
+ handle);
+ if (timeout_handle == 0) {
+ timeout_handle = g_timeout_add(PENDING_SIGNAL_INTERVAL,
+ __flush_pending_signal, NULL);
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
static int __sigchild_action(pid_t dead_pid)
{
- if (dead_pid <= 0)
- goto end;
+ int ret;
+ struct pending_signal *handle;
- __send_app_dead_signal_dbus(dead_pid);
+ if (dead_pid <= 0)
+ return 0;
+
+ ret = __send_app_dead_signal(dead_pid);
+ if (ret < 0) {
+ handle = __create_pending_signal(NULL, dead_pid, APP_DEAD);
+ pending_signal_list = g_list_append(pending_signal_list,
+ handle);
+ if (timeout_handle == 0) {
+ timeout_handle = g_timeout_add(PENDING_SIGNAL_INTERVAL,
+ __flush_pending_signal, NULL);
+ }
+ }
_delete_sock_path(dead_pid, getuid());
-
__socket_garbage_collector();
-end:
+
return 0;
}
-static void __launchpad_process_sigchld(struct signalfd_siginfo *info)
+void _signal_process_sigchld(struct signalfd_siginfo *info)
{
int status;
pid_t child_pid;
@@ -167,7 +292,7 @@ static void __launchpad_process_sigchld(struct signalfd_siginfo *info)
}
}
-static inline int __signal_init(void)
+int _signal_init(void)
{
int i;
GError *error = NULL;
@@ -198,7 +323,7 @@ static inline int __signal_init(void)
return 0;
}
-static inline int __signal_get_sigchld_fd(void)
+int _signal_get_sigchld_fd(void)
{
sigset_t mask;
int sfd;
@@ -218,7 +343,7 @@ static inline int __signal_get_sigchld_fd(void)
return sfd;
}
-static inline int __signal_unblock_sigchld(void)
+int _signal_unblock_sigchld(void)
{
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
_E("SIG_SETMASK error");
@@ -229,16 +354,12 @@ static inline int __signal_unblock_sigchld(void)
return 0;
}
-static inline int __signal_fini(void)
+void _signal_fini(void)
{
#ifndef PRELOAD_ACTIVATE
int i;
-#endif
-#ifndef PRELOAD_ACTIVATE
for (i = 0; i < _NSIG; i++)
signal(i, SIG_DFL);
#endif
- return 0;
}
-