diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-11-29 11:45:19 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-11-29 15:47:57 +0900 |
commit | 62093d99d4d73668c1133b13fb496baf5e56be7a (patch) | |
tree | 7ff8cd3d38e1743490cc3bfe9e63d66ef26124ba | |
parent | 4f33c81bdbf94cf15b7cf56fcb05b849f8f99581 (diff) |
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
-rw-r--r-- | src/lib/evas/cserve2/evas_cs2_client.c | 22 |
1 files 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 0d5fe2cef..c5ef5948a 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; } |