jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=62093d99d4d73668c1133b13fb496baf5e56be7a

commit 62093d99d4d73668c1133b13fb496baf5e56be7a
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Fri Nov 29 11:45:19 2013 +0900

    evas/cserve2: Fix interrupt on select in edje_cc
    
    Summary:
    Block SIGCHLD during select().
    This fixes a bug with edje_cc when EVAS_CSERVE2=1: Fixes T464.
    
    select() used to return prematurately with EINTR because the
    app received some unexpected signals. In particular SIGCHLD
    is received when a child terminates, but this is not a reason
    to cancel the image load.
    
    In theory, all blocked signals in pselect() should be pending
    until pselect returns, so any SIGCHLD should still trigger
    the app's signal handler.
    
    Reviewers: cedric
    
    CC: raster, cedric
    
    Maniphest Tasks: T464
    
    Differential Revision: https://phab.enlightenment.org/D357
---
 src/lib/evas/cserve2/evas_cs2_client.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/src/lib/evas/cserve2/evas_cs2_client.c 
b/src/lib/evas/cserve2/evas_cs2_client.c
index 0d5fe2c..c5ef594 100644
--- a/src/lib/evas/cserve2/evas_cs2_client.c
+++ b/src/lib/evas/cserve2/evas_cs2_client.c
@@ -8,6 +8,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <signal.h>
 
 #include <Eina.h>
 
@@ -600,6 +601,14 @@ _server_dispatch_until(unsigned int rid)
 {
    Eina_Bool failed;
    unsigned int rrid;
+   sigset_t sigmask;
+
+   // We want to block some signals from interrupting pselect().
+   // If the kernel implements TIF_RESTORE_SIGMASK, the
+   // signal handlers should be called right after pselect
+   // SIGCHLD: apps can have children that just terminated
+   sigprocmask(0, NULL, &sigmask);
+   sigaddset(&sigmask, SIGCHLD);
 
    while (1)
      {
@@ -609,7 +618,7 @@ _server_dispatch_until(unsigned int rid)
         else if (failed)
           {
              fd_set rfds;
-             struct timeval tv;
+             struct timespec ts;
              int sel;
 
              if (socketfd == -1)
@@ -625,9 +634,9 @@ _server_dispatch_until(unsigned int rid)
              //DBG("Waiting for request %d...", rid);
              FD_ZERO(&rfds);
              FD_SET(socketfd, &rfds);
-             tv.tv_sec = TIMEOUT / 1000;
-             tv.tv_usec = TIMEOUT * 1000;
-             sel = select(socketfd + 1, &rfds, NULL, NULL, &tv);
+             ts.tv_sec = TIMEOUT / 1000;
+             ts.tv_nsec = (TIMEOUT % 1000) * 1000000;
+             sel = pselect(socketfd + 1, &rfds, NULL, NULL, &ts, &sigmask);
              if (sel == -1)
                {
                   ERR("select() failed: [%d] %s", errno, strerror(errno));
@@ -638,6 +647,11 @@ _server_dispatch_until(unsigned int rid)
                    */
                   if (errno == EINTR)
                     {
+                       /* FIXME: Actually we might want to cancel our request
+                        * ONLY when we received a SIGINT, but at this point
+                        * there is no way we can know which signal we got.
+                        * So we assume SIGINT and abandon this request.
+                        */
                        DBG("giving up on request %d after interrupt", rid);
                        return EINA_FALSE;
                     }

-- 


Reply via email to