[PATCH] Keep SIGALRM restart flag after Popen

Daniel Drake drake at endlessm.com
Wed May 20 12:16:12 PDT 2015


Commit de0e6073e3f122 added SA_RESTART to the SIGALRM handler.
However, the Popen code tears down and recreates the SIGALRM handler
via OsSignal(), and this flag is dropped at this time.

Clean the code to use just a single codepath for creating this
signal handler, always applying SA_RESTART.

Signed-off-by: Daniel Drake <drake at endlessm.com>
---
 os/utils.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/os/utils.c b/os/utils.c
index 7fd395b..47b0b80 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1228,14 +1228,15 @@ SmartScheduleTimer(int sig)
     SmartScheduleTime += SmartScheduleInterval;
 }
 
-void
-SmartScheduleInit(void)
+static int
+SmartScheduleEnable(void)
 {
+    int ret = 0;
 #ifdef SMART_SCHEDULE_POSSIBLE
     struct sigaction act;
 
     if (SmartScheduleDisable)
-        return;
+        return 0;
 
     memset((char *) &act, 0, sizeof(struct sigaction));
 
@@ -1243,11 +1244,40 @@ SmartScheduleInit(void)
     act.sa_handler = SmartScheduleTimer;
     sigemptyset(&act.sa_mask);
     sigaddset(&act.sa_mask, SIGALRM);
-    if (sigaction(SIGALRM, &act, 0) < 0) {
+    ret = sigaction(SIGALRM, &act, 0);
+#endif
+    return ret;
+}
+
+static int
+SmartSchedulePause(void)
+{
+    int ret = 0;
+#ifdef SMART_SCHEDULE_POSSIBLE
+    struct sigaction act;
+
+    if (SmartScheduleDisable)
+        return 0;
+
+    memset((char *) &act, 0, sizeof(struct sigaction));
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    ret = sigaction(SIGALRM, &act, 0);
+#endif
+    return ret;
+}
+
+void
+SmartScheduleInit(void)
+{
+    if (SmartScheduleDisable)
+        return;
+
+    if (SmartScheduleEnable() < 0) {
         perror("sigaction for smart scheduler");
         SmartScheduleDisable = TRUE;
     }
-#endif
 }
 
 #ifdef SIG_BLOCK
@@ -1422,8 +1452,6 @@ static struct pid {
     int pid;
 } *pidlist;
 
-OsSigHandlerPtr old_alarm = NULL;       /* XXX horrible awful hack */
-
 void *
 Popen(const char *command, const char *type)
 {
@@ -1446,8 +1474,7 @@ Popen(const char *command, const char *type)
     }
 
     /* Ignore the smart scheduler while this is going on */
-    old_alarm = OsSignal(SIGALRM, SIG_IGN);
-    if (old_alarm == SIG_ERR) {
+    if (SmartSchedulePause() < 0) {
         close(pdes[0]);
         close(pdes[1]);
         free(cur);
@@ -1460,7 +1487,7 @@ Popen(const char *command, const char *type)
         close(pdes[0]);
         close(pdes[1]);
         free(cur);
-        if (OsSignal(SIGALRM, old_alarm) == SIG_ERR)
+        if (SmartScheduleEnable() < 0)
             perror("signal");
         return NULL;
     case 0:                    /* child */
@@ -1635,7 +1662,7 @@ Pclose(void *iop)
     /* allow EINTR again */
     OsReleaseSignals();
 
-    if (old_alarm && OsSignal(SIGALRM, old_alarm) == SIG_ERR) {
+    if (SmartScheduleEnable() < 0) {
         perror("signal");
         return -1;
     }
-- 
2.1.4



More information about the xorg-devel mailing list