xserver: Branch 'master' - 2 commits

Adam Jackson ajax at kemper.freedesktop.org
Mon Sep 21 08:07:30 PDT 2015


 hw/xfree86/os-support/shared/sigio.c |    2 -
 os/utils.c                           |   50 +++++++++++++++++++++++++++--------
 2 files changed, 40 insertions(+), 12 deletions(-)

New commits:
commit 1f915e8b524dd02011158aa038935970684c7630
Author: Daniel Drake <drake at endlessm.com>
Date:   Wed May 20 13:16:12 2015 -0600

    Keep SIGALRM restart flag after Popen
    
    Commit 94ab7455 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.
    
    [ajax: Fixed commit id]
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Daniel Drake <drake at endlessm.com>

diff --git a/os/utils.c b/os/utils.c
index 9b6fb30..b45719e 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1243,14 +1243,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));
 
@@ -1259,11 +1260,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
@@ -1438,8 +1468,6 @@ static struct pid {
     int pid;
 } *pidlist;
 
-OsSigHandlerPtr old_alarm = NULL;       /* XXX horrible awful hack */
-
 void *
 Popen(const char *command, const char *type)
 {
@@ -1462,8 +1490,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);
@@ -1476,7 +1503,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 */
@@ -1651,7 +1678,7 @@ Pclose(void *iop)
     /* allow EINTR again */
     OsReleaseSignals();
 
-    if (old_alarm && OsSignal(SIGALRM, old_alarm) == SIG_ERR) {
+    if (SmartScheduleEnable() < 0) {
         perror("signal");
         return -1;
     }
commit 94ab7455abc213fc96760e29ab2e943ec682fb22
Author: Daniel Drake <drake at endlessm.com>
Date:   Tue May 12 16:39:22 2015 -0600

    Allow system call restarts upon signal interruption
    
    The X server frequently deals with SIGIO and SIGALRM interruptions.
    If process execution is inside certain blocking system calls
    when these signals arrive, e.g. with the kernel blocked on
    a contended semaphore, the system calls will be interrupted.
    
    Some system calls are automatically restartable (the kernel re-executes
    them with the same parameters once the signal handler returns) but
    only if the signal handler allows it.
    
    Set SA_RESTART on the signal handlers to enable this convenient
    behaviour.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Daniel Drake <drake at endlessm.com>

diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c
index 45949f7..c746d02 100644
--- a/hw/xfree86/os-support/shared/sigio.c
+++ b/hw/xfree86/os-support/shared/sigio.c
@@ -178,7 +178,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
             }
             sigemptyset(&sa.sa_mask);
             sigaddset(&sa.sa_mask, SIGIO);
-            sa.sa_flags = 0;
+            sa.sa_flags = SA_RESTART;
             sa.sa_handler = xf86SIGIO;
             sigaction(SIGIO, &sa, &osa);
             xf86SigIOFuncs[i].fd = fd;
diff --git a/os/utils.c b/os/utils.c
index 868eb04..9b6fb30 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1255,6 +1255,7 @@ SmartScheduleInit(void)
     memset((char *) &act, 0, sizeof(struct sigaction));
 
     /* Set up the timer signal function */
+    act.sa_flags = SA_RESTART;
     act.sa_handler = SmartScheduleTimer;
     sigemptyset(&act.sa_mask);
     sigaddset(&act.sa_mask, SIGALRM);


More information about the xorg-commit mailing list