efl - threads and signals - make efl work on "insane" os's with signals
authorJee-Yong Um <jc9.um@samsung.com>
Wed, 7 Dec 2016 04:38:51 +0000 (13:38 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Mon, 2 Jan 2017 07:23:59 +0000 (16:23 +0900)
==========================================================================
commit aeeda1f77d1b21b15e916852baac06bb530618e2
Author: Carsten Haitzler (Rasterman) <raster@rasterman.com>
Date:   Mon Jul 4 23:47:25 2016 +0900

    efl - threads and signals - make efl work on "insane" os's with signals

    so. on linux signals are delivered to the main process thread/loop.
    thats' where signal handlers are set up and always run. this is sane.
    it's predicatble. but of course this is not the same in bsd land.
    there "just send the signal to any old thread and call the signal
    handler there" seems to tbe the order of the day. this explains why
    wer are losing sigchld signals in edje_cc - it's heavily threaded and
    bsd is just randombly picking a thread to call it on.

    this fixes that. in theory. i hope. i can't test, but putting it in to
    share

    @fix
==========================================================================

Signed-Off-By: Jee-Yong Um <jc9.um@samsung.com>
Change-Id: I02fd04ff175a81fda89a8a36ecf6007f3899d40a

src/bin/evas/evas_cserve2_slaves.c
src/lib/eina/eina_debug_monitor.c
src/lib/eina/eina_thread.c
src/modules/emotion/xine/emotion_xine.c

index 3958046..f790357 100644 (file)
@@ -507,6 +507,7 @@ cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Rea
    pthread_t tid;
    int child[2], parent[2];
    int flags;
+   sigset_t oldset, newset;
 
    s = calloc(1, sizeof(Slave_Thread));
    if (!s)
@@ -550,8 +551,23 @@ cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Rea
    sd->cb = thread_cb;
    sd->cb_data = thread_data;
 
+   sigemptyset(&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
+   sigprocmask(SIG_BLOCK, &newset, &oldset);
    if (pthread_create(&tid, &slave_thread_attr, _slave_thread_cb, sd))
      {
+        sigprocmask(SIG_SETMASK, &oldset, NULL);
         ERR("Could not start slave thread.");
         free(s);
         free(sd);
@@ -561,6 +577,7 @@ cserve2_slave_thread_run(Slave_Thread_Cb thread_cb, void *thread_data, Slave_Rea
         close(parent[1]);
         return NULL;
      }
+   sigprocmask(SIG_SETMASK, &oldset, NULL);
 
    s->tid = tid;
    s->tdata = sd;
index d76618f..e490aec 100644 (file)
@@ -20,6 +20,7 @@
 #include "eina_types.h"
 #include "eina_evlog.h"
 #include "eina_util.h"
+#include <signal.h>
 
 #ifdef EINA_HAVE_DEBUG
 
@@ -334,11 +335,27 @@ void
 _eina_debug_monitor_thread_start(void)
 {
    int err;
+   sigset_t oldset, newset;
 
    // if it's already running - we're good.
    if (_monitor_thread_runs) return;
    // create debug monitor thread
+   sigemptyset(&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
+   sigprocmask(SIG_BLOCK, &newset, &oldset);
    err = pthread_create(&_monitor_thread, NULL, _eina_debug_monitor, NULL);
+   sigprocmask(SIG_SETMASK, &oldset, NULL);
    if (err != 0)
      {
         fprintf(stderr, "EINA DEBUG ERROR: Can't create debug thread!\n");
index 3216719..06e40f3 100644 (file)
 
 #include "eina_debug.h"
 
-# include <pthread.h>
-# include <errno.h>
+#include <pthread.h>
+#include <errno.h>
+#ifndef _WIN32
+# include <signal.h>
+#endif
 
 #ifdef EINA_HAVE_PTHREAD_AFFINITY
 #ifndef __linux__
@@ -57,6 +60,9 @@ _eina_thread_create(Eina_Thread *t, int affinity, void *(*func)(void *data), voi
 {
    int err;
    pthread_attr_t attr;
+#ifndef _WIN32
+   sigset_t oldset, newset;
+#endif
 
    pthread_attr_init(&attr);
    if (affinity >= 0)
@@ -74,7 +80,26 @@ _eina_thread_create(Eina_Thread *t, int affinity, void *(*func)(void *data), voi
      }
 
    /* setup initial locks */
+#ifndef _WIN32
+   sigemptyset(&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
+   pthread_sigmask(SIG_BLOCK, &newset, &oldset);
+#endif
    err = pthread_create((pthread_t *)t, &attr, func, data);
+#ifndef _WIN32
+   pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+#endif
    pthread_attr_destroy(&attr);
 
    if (err == 0) return EINA_TRUE;
index 6ff6de1..0e55b3a 100644 (file)
@@ -5,6 +5,7 @@
 #include <Eina.h>
 #include <Evas.h>
 #include <Ecore.h>
+#include <signal.h>
 
 #include "emotion_modules.h"
 #include "emotion_xine.h"
@@ -322,6 +323,7 @@ em_add(const Emotion_Engine *api EINA_UNUSED,
 {
    Emotion_Xine_Video *ev;
    int fds[2];
+   sigset_t oldset, newset;
 
    ev = calloc(1, sizeof(Emotion_Xine_Video));
    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, NULL);
@@ -366,9 +368,24 @@ em_add(const Emotion_Engine *api EINA_UNUSED,
    
    pthread_cond_init(&(ev->get_pos_len_cond), NULL);
    pthread_mutex_init(&(ev->get_pos_len_mutex), NULL);
+   sigemptyset(&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
+   sigprocmask(SIG_BLOCK, &newset, &oldset);
    pthread_create(&ev->get_pos_len_th, NULL, _em_get_pos_len_th, ev);
-
    pthread_create(&ev->slave_th, NULL, _em_slave, ev);
+   sigprocmask(SIG_SETMASK, &oldset, NULL);
+
    pthread_detach(ev->slave_th);
    _em_slave_event(ev, 1, NULL);