summaryrefslogtreecommitdiff
path: root/src/lib/evas/cserve2
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2013-11-29 11:45:19 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2013-11-29 15:47:57 +0900
commit62093d99d4d73668c1133b13fb496baf5e56be7a (patch)
tree7ff8cd3d38e1743490cc3bfe9e63d66ef26124ba /src/lib/evas/cserve2
parent4f33c81bdbf94cf15b7cf56fcb05b849f8f99581 (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
Diffstat (limited to 'src/lib/evas/cserve2')
-rw-r--r--src/lib/evas/cserve2/evas_cs2_client.c22
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 0d5fe2cefc..c5ef5948a4 100644
--- a/src/lib/evas/cserve2/evas_cs2_client.c
+++ b/src/lib/evas/cserve2/evas_cs2_client.c
@@ -8,6 +8,7 @@
8#include <sys/stat.h> 8#include <sys/stat.h>
9#include <unistd.h> 9#include <unistd.h>
10#include <fcntl.h> 10#include <fcntl.h>
11#include <signal.h>
11 12
12#include <Eina.h> 13#include <Eina.h>
13 14
@@ -600,6 +601,14 @@ _server_dispatch_until(unsigned int rid)
600{ 601{
601 Eina_Bool failed; 602 Eina_Bool failed;
602 unsigned int rrid; 603 unsigned int rrid;
604 sigset_t sigmask;
605
606 // We want to block some signals from interrupting pselect().
607 // If the kernel implements TIF_RESTORE_SIGMASK, the
608 // signal handlers should be called right after pselect
609 // SIGCHLD: apps can have children that just terminated
610 sigprocmask(0, NULL, &sigmask);
611 sigaddset(&sigmask, SIGCHLD);
603 612
604 while (1) 613 while (1)
605 { 614 {
@@ -609,7 +618,7 @@ _server_dispatch_until(unsigned int rid)
609 else if (failed) 618 else if (failed)
610 { 619 {
611 fd_set rfds; 620 fd_set rfds;
612 struct timeval tv; 621 struct timespec ts;
613 int sel; 622 int sel;
614 623
615 if (socketfd == -1) 624 if (socketfd == -1)
@@ -625,9 +634,9 @@ _server_dispatch_until(unsigned int rid)
625 //DBG("Waiting for request %d...", rid); 634 //DBG("Waiting for request %d...", rid);
626 FD_ZERO(&rfds); 635 FD_ZERO(&rfds);
627 FD_SET(socketfd, &rfds); 636 FD_SET(socketfd, &rfds);
628 tv.tv_sec = TIMEOUT / 1000; 637 ts.tv_sec = TIMEOUT / 1000;
629 tv.tv_usec = TIMEOUT * 1000; 638 ts.tv_nsec = (TIMEOUT % 1000) * 1000000;
630 sel = select(socketfd + 1, &rfds, NULL, NULL, &tv); 639 sel = pselect(socketfd + 1, &rfds, NULL, NULL, &ts, &sigmask);
631 if (sel == -1) 640 if (sel == -1)
632 { 641 {
633 ERR("select() failed: [%d] %s", errno, strerror(errno)); 642 ERR("select() failed: [%d] %s", errno, strerror(errno));
@@ -638,6 +647,11 @@ _server_dispatch_until(unsigned int rid)
638 */ 647 */
639 if (errno == EINTR) 648 if (errno == EINTR)
640 { 649 {
650 /* FIXME: Actually we might want to cancel our request
651 * ONLY when we received a SIGINT, but at this point
652 * there is no way we can know which signal we got.
653 * So we assume SIGINT and abandon this request.
654 */
641 DBG("giving up on request %d after interrupt", rid); 655 DBG("giving up on request %d after interrupt", rid);
642 return EINA_FALSE; 656 return EINA_FALSE;
643 } 657 }