cedric pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=9637b07ec761f02a734d48c832a25db4d35649f4

commit 9637b07ec761f02a734d48c832a25db4d35649f4
Author: Jean-Philippe Andre <j...@videolan.org>
Date:   Fri Nov 8 16:56:28 2013 +0900

    e/cserve2: add restart code for cserve2
    
    Summary: If cserve2 crashes, enlightenment_start will respawn it again.
    
    Test Plan:
    Start E18 (in Xephyr maybe) with E_CSERVE set.
    Randomly kill evas_cserve2 and enlightenment, and log out from E.
    
    I need review for this patch as I'm not sure about all the ptrace stuff
    lying around.
    
    Reviewers: cedric
    
    CC: raster, zmike
    
    Differential Revision: https://phab.enlightenment.org/D287
    
    Signed-off-by: Cedric Bail <cedric.b...@samsung.com>
---
 src/bin/e_start_main.c | 104 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 81 insertions(+), 23 deletions(-)

diff --git a/src/bin/e_start_main.c b/src/bin/e_start_main.c
index 3cd7122..2629155 100644
--- a/src/bin/e_start_main.c
+++ b/src/bin/e_start_main.c
@@ -22,6 +22,10 @@
 #include <Eina.h>
 #include <Evas.h>
 
+#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
+# define E_CSERVE
+#endif
+
 static Eina_Bool stop_ptrace = EINA_FALSE;
 
 static void env_set(const char *var, const char *val);
@@ -235,6 +239,32 @@ _sigusr1(int x __UNUSED__, siginfo_t *info __UNUSED__, 
void *data __UNUSED__)
    sigaction(SIGUSR1, &action, NULL);
 }
 
+#ifdef E_CSERVE
+static pid_t
+_cserve2_start()
+{
+   pid_t cs_child;
+   cs_child = fork();
+   if (cs_child == 0)
+     {
+        char *cs_args[2] = { NULL, NULL };
+
+        cs_args[0] = (char *)evas_cserve_path_get();
+        execv(cs_args[0], cs_args);
+        exit(-1);
+     }
+   else if (cs_child > 0)
+     {
+        putenv("EVAS_CSERVE2=1");
+     }
+   else
+     {
+        unsetenv("EVAS_CSERVE2");
+     }
+   return cs_child;
+}
+#endif
+
 int
 main(int argc, char **argv)
 {
@@ -247,8 +277,9 @@ main(int argc, char **argv)
    Eina_Bool really_know = EINA_FALSE;
    struct sigaction action;
    pid_t child = -1;
-#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
+#ifdef E_CSERVE
    pid_t cs_child = -1;
+   Eina_Bool cs_use = EINA_FALSE;
 #endif
 #if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
    !defined(__FreeBSD_kernel__) && !(defined (__MACH__) && defined (__APPLE__))
@@ -424,31 +455,19 @@ main(int argc, char **argv)
 
 #if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__FreeBSD__) && \
    !defined(__FreeBSD_kernel__) && !(defined (__MACH__) && defined (__APPLE__))
+
+#ifdef E_CSERVE
+   if (getenv("E_CSERVE"))
+     {
+        cs_use = EINA_TRUE;
+        cs_child = _cserve2_start();
+     }
+#endif
+
    /* Now looping until */
    while (restart)
      {
         stop_ptrace = EINA_FALSE;
-#if (EVAS_VERSION_MAJOR > 1) || (EVAS_VERSION_MINOR >= 8)
-        if (getenv("E_CSERVE"))
-          {
-             if (cs_child < 0)
-               {             
-                  cs_child = fork();
-                  if (cs_child == 0) 
-                    {
-                       char *cs_args[2] = { NULL, NULL };
-                       
-                       cs_args[0] = (char *)evas_cserve_path_get();
-                       execv(cs_args[0], cs_args);
-                       exit(-1);
-                    }
-                  else if (cs_child > 0)
-                    {
-                       putenv("EVAS_CSERVE2=1");
-                    }
-               }
-          }
-#endif
 
         child = fork();
 
@@ -487,7 +506,12 @@ main(int argc, char **argv)
                   Eina_Bool remember_sigill = EINA_FALSE;
                   Eina_Bool remember_sigusr1 = EINA_FALSE;
 
-                  result = waitpid(child, &status, 0);
+                  result = waitpid(child, &status, WNOHANG);
+                  if (!result)
+                    {
+                       /* Wait for evas_cserve2 and E */
+                       result = waitpid(-1, &status, 0);
+                    }
 
                   if (result == child)
                     {
@@ -609,11 +633,45 @@ main(int argc, char **argv)
                               }
                          }
                     }
+#ifdef E_CSERVE
+                  else if (cs_use && (result == cs_child))
+                    {
+                       if (WIFSIGNALED(status))
+                         {
+                            printf("E - cserve2 terminated with signal %d\n",
+                                   WTERMSIG(status));
+                            cs_child = _cserve2_start();
+                         }
+                       else if (WIFEXITED(status))
+                         {
+                            printf("E - cserve2 exited with code %d\n",
+                                   WEXITSTATUS(status));
+                            cs_child = -1;
+                         }
+                    }
+#endif
                }
           }
      }
 #endif
 
+#ifdef E_CSERVE
+   if (cs_child > 0)
+     {
+        pid_t result;
+        int status;
+
+        alarm(2);
+        kill(cs_child, SIGINT);
+        result = waitpid(cs_child, &status, 0);
+        if (result != cs_child)
+          {
+             printf("E - cserve2 did not shutdown in 2 seconds, killing!\n");
+             kill(cs_child, SIGKILL);
+          }
+     }
+#endif
+
    return -1;
 }
 

-- 


Reply via email to