[UI Thread] Fix duplicated initialization of ecore signal handler 28/273928/2 submit/tizen/20220419.070532
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 18 Apr 2022 06:49:57 +0000 (15:49 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 18 Apr 2022 06:56:20 +0000 (15:56 +0900)
To prevent duplicated initialization of the ecore signal handler, this patch add
a new flag to check whether the ecore signal is initialized or not.
Before creating a new child process, the ecore signal handler blocks signals to
stop inheriting signal handlers. After creating a new child process,
the ecore signal handler unblocks signals.

Change-Id: I5f8e2efffec98e9cd3e4387420ceb7126aa01d84
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/lib/ecore/ecore_signal.c

index bff4426..055fbdd 100644 (file)
@@ -58,6 +58,8 @@ static struct sigaction sa_prev_sigterm;
 #ifdef SIGPWR
 static struct sigaction sa_prev_sigpwr;
 #endif
+static sigset_t oldset;
+static int sa_initialized;
 #endif /* TIZEN_FEATURE_SAVE_PREV_ACTIONS */
 
 volatile int pipe_dead = 0;
@@ -196,8 +198,8 @@ _ecore_signal_is_sigign(struct sigaction *action)
        !_ecore_signal_is_sa_siginfo(action)) && action->sa_handler == SIG_IGN;
 }
 
-static void
-_ecore_signal_invoke_prev_sigaction(int sig, siginfo_t* si, void *context)
+static struct sigaction *
+_ecore_signal_sigaction_get(int sig)
 {
    struct sigaction *sa;
 
@@ -240,6 +242,14 @@ _ecore_signal_invoke_prev_sigaction(int sig, siginfo_t* si, void *context)
        break;
     }
 
+   return sa;
+}
+
+static void
+_ecore_signal_invoke_prev_sigaction(int sig, siginfo_t* si, void *context)
+{
+   struct sigaction *sa = _ecore_signal_sigaction_get(sig);
+
    if (sa == NULL) return;
 
    if (_ecore_signal_is_sigign(sa) || _ecore_signal_is_sigdfl(sa)) return;
@@ -324,6 +334,67 @@ _ecore_signal_callback_set(int sig, Signal_Handler func, struct sigaction *sa_pr
    sigemptyset(&sa.sa_mask);
    sigaction(sig, &sa, sa_prev);
 }
+
+static void
+_ecore_signal_atfork_prepare(void)
+{
+   sigset_t newset;
+
+   sigaddset(&newset, SIGPIPE);
+   sigaddset(&newset, SIGALRM);
+   sigaddset(&newset, SIGCHLD);
+   sigaddset(&newset, SIGUSR1);
+   sigaddset(&newset, SIGUSR2);
+   sigaddset(&newset, SIGHUP);
+   sigaddset(&newset, SIGQUIT);
+   sigaddset(&newset, SIGINT);
+   sigaddset(&newset, SIGTERM);
+# ifdef SIGPWR
+   sigaddset(&newset, SIGPWR);
+# endif
+
+   if (sigprocmask(SIG_BLOCK, &newset, &oldset) != 0)
+     ERR("sigprocmask() is failed. errno(%d)", errno);
+}
+
+static void
+_ecore_signal_atfork_parent(void)
+{
+   if (sigprocmask(SIG_SETMASK, &oldset, NULL) != 0)
+     ERR("sigprocmask() is failed. errno(%d)", errno);
+}
+
+static void
+_ecore_signal_callback_reset(int sig, struct sigaction *sa)
+{
+   memset(sa, 0, sizeof(struct sigaction));
+   sigemptyset(&sa->sa_mask);
+   sa->sa_handler = SIG_DFL;
+   sa->sa_flags = 0;
+   sigaction(sig, sa, NULL);
+}
+
+static void
+_ecore_signal_atfork_child(void)
+{
+   _ecore_signal_callback_reset(SIGPIPE, &sa_prev_sigpipe);
+   _ecore_signal_callback_reset(SIGALRM, &sa_prev_sigalrm);
+   _ecore_signal_callback_reset(SIGCHLD, &sa_prev_sigchld);
+   _ecore_signal_callback_reset(SIGUSR1, &sa_prev_sigusr1);
+   _ecore_signal_callback_reset(SIGUSR2, &sa_prev_sigusr2);
+   _ecore_signal_callback_reset(SIGHUP,  &sa_prev_sighup);
+   _ecore_signal_callback_reset(SIGQUIT, &sa_prev_sigquit);
+   _ecore_signal_callback_reset(SIGINT,  &sa_prev_sigint);
+   _ecore_signal_callback_reset(SIGTERM, &sa_prev_sigterm);
+#ifdef SIGPWR
+   _ecore_signal_callback_reset(SIGPWR,  &sa_prev_sigpwr);
+#endif
+
+   if (sigprocmask(SIG_SETMASK, &oldset, NULL) != 0)
+     ERR("sigprocmask() is failed. errno(%d)", errno);
+
+   sa_initialized = 0;
+}
 #else
 static void
 _ecore_signal_callback_set(int sig, Signal_Handler func)
@@ -343,6 +414,9 @@ _signalhandler_setup(void)
    sigset_t newset;
 
 #ifdef TIZEN_FEATURE_SAVE_PREV_ACTIONS
+   if (sa_initialized)
+     return;
+
    _ecore_signal_callback_set(SIGPIPE, _ecore_signal_callback, &sa_prev_sigpipe);
    _ecore_signal_callback_set(SIGALRM, _ecore_signal_callback, &sa_prev_sigalrm);
    _ecore_signal_callback_set(SIGCHLD, _ecore_signal_callback, &sa_prev_sigchld);
@@ -355,6 +429,8 @@ _signalhandler_setup(void)
 #ifdef SIGPWR
    _ecore_signal_callback_set(SIGPWR,  _ecore_signal_callback, &sa_prev_sigpwr);
 #endif
+
+   pthread_atfork(_ecore_signal_atfork_prepare, _ecore_signal_atfork_parent, _ecore_signal_atfork_child);
 #else
    _ecore_signal_callback_set(SIGPIPE, _ecore_signal_callback);
    _ecore_signal_callback_set(SIGALRM, _ecore_signal_callback);
@@ -386,6 +462,10 @@ _signalhandler_setup(void)
 # endif
    pthread_sigmask(SIG_UNBLOCK, &newset, NULL);
 #endif
+
+#ifdef TIZEN_FEATURE_SAVE_PREV_ACTIONS
+   sa_initialized = 1;
+#endif
 }
 
 static void