xserver: Branch 'master' - 12 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Jul 4 11:47:13 PDT 2012


 Xi/extinit.c                         |    2 
 dix/touch.c                          |   11 ++
 hw/dmx/input/dmxevents.c             |   24 +++---
 hw/dmx/input/dmxsigio.c              |   22 -----
 hw/dmx/input/dmxsigio.h              |    2 
 hw/kdrive/ephyr/ephyr.c              |   24 ------
 hw/kdrive/src/kinput.c               |   40 ++--------
 hw/xfree86/common/xf86Config.c       |    1 
 hw/xfree86/common/xf86Cursor.c       |   12 +--
 hw/xfree86/common/xf86Events.c       |   14 +--
 hw/xfree86/common/xf86Init.c         |    9 +-
 hw/xfree86/common/xf86PM.c           |   12 +--
 hw/xfree86/loader/loader.c           |    6 +
 hw/xfree86/loader/loader.h           |    1 
 hw/xfree86/loader/loadmod.c          |    2 
 hw/xfree86/os-support/shared/sigio.c |   24 +-----
 include/os.h                         |    6 +
 os/utils.c                           |   54 +++++++++++++-
 test/Makefile.am                     |    3 
 test/os.c                            |  130 +++++++++++++++++++++++++++++++++++
 xkb/xkbAccessX.c                     |   10 +-
 21 files changed, 263 insertions(+), 146 deletions(-)

New commits:
commit 258abbf823f753757e4dddc13ef495f4024680db
Author: Michal Srb <msrb at suse.com>
Date:   Thu Jun 28 17:17:12 2012 +0200

    Look for ModuleData only in appropriate library
    
    LoaderSymbol calls dlsym with RTLD_DEFAULT pseudo handle making it search in
    every loaded library. In addition glibc adds NODELETE flag to the library
    containing the symbol.
    
    It's used in doLoadModule to locate <modulename>ModuleData symbol, the
    module's library gets the flag and is kept in memory even after it is
    unloaded.
    
    This patch adds LoaderSymbolFromModule function that looks for symbol only in
    library specified by handle. That way the NODELETE flag isn't added.
    
    This glibc behavior doesn't seem to be documented, but even if other
    implementations differ, there is no reason to search ModuleData symbol outside
    the module's library.
    
    Signed-off-by: Michal Srb <msrb at suse.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
    
    v2: Switch LoaderSymbolFromModule arguments order.
        Correct description.
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/loader/loader.c b/hw/xfree86/loader/loader.c
index edaefb8..5fbea38 100644
--- a/hw/xfree86/loader/loader.c
+++ b/hw/xfree86/loader/loader.c
@@ -160,6 +160,12 @@ LoaderSymbol(const char *name)
     return NULL;
 }
 
+void *
+LoaderSymbolFromModule(void *handle, const char *name)
+{
+    return dlsym(handle, name);
+}
+
 void
 LoaderUnload(const char *name, void *handle)
 {
diff --git a/hw/xfree86/loader/loader.h b/hw/xfree86/loader/loader.h
index 5cadd5a..c89c641 100644
--- a/hw/xfree86/loader/loader.h
+++ b/hw/xfree86/loader/loader.h
@@ -72,5 +72,6 @@ extern unsigned long LoaderOptions;
 
 /* Internal Functions */
 void *LoaderOpen(const char *, int *, int *);
+void *LoaderSymbolFromModule(void *, const char *);
 
 #endif                          /* _LOADER_H */
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index 72020a5..dd20573 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -956,7 +956,7 @@ doLoadModule(const char *module, const char *path, const char **subdirlist,
             *errmin = 0;
         goto LoadModule_fail;
     }
-    initdata = LoaderSymbol(p);
+    initdata = LoaderSymbolFromModule(ret->handle, p);
     if (initdata) {
         ModuleSetupProc setup;
         ModuleTearDownProc teardown;
commit d84f0f823eeeecdf0498aadd3fbb1d11dabc0837
Merge: 12bfb4c... d04dfe3...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jul 4 21:23:48 2012 +1000

    Merge branch 'sigio-vt-switch-issues' into for-keith
    
    Conflicts:
    	test/Makefile.am
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --cc test/Makefile.am
index e5b25c9,436351c..15c51ed
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@@ -5,7 -5,7 +5,7 @@@ if XOR
  # Tests that require at least some DDX functions in order to fully link
  # For now, requires xf86 ddx, could be adjusted to use another
  SUBDIRS += xi2
- noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest signal-logging
 -noinst_PROGRAMS += xkb input xtest misc fixes xfree86  hashtabletest os
++noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest os signal-logging
  endif
  check_LTLIBRARIES = libxservertest.la
  
@@@ -36,8 -36,8 +36,9 @@@ misc_LDADD=$(TEST_LDADD
  fixes_LDADD=$(TEST_LDADD)
  xfree86_LDADD=$(TEST_LDADD)
  touch_LDADD=$(TEST_LDADD)
 +signal_logging_LDADD=$(TEST_LDADD)
  hashtabletest_LDADD=$(TEST_LDADD) $(top_srcdir)/Xext/hashtable.c
+ os_LDADD=$(TEST_LDADD)
  
  libxservertest_la_LIBADD = $(XSERVER_LIBS)
  if XORG
commit 12bfb4cf1bebb66d2c2eb76b93c18a2915b865e5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jun 26 09:19:33 2012 +1000

    Xi: extend PropagateMask to EMASKSIZE
    
    Number of devices is 2 + MAXDEVICES, with index 0 and 1 reserved for
    XIAll{Master}Devices. At the current size, PropagateMask would be overrun in
    RecalculateDeviceDeliverableEvents().
    
    Found by Coverity.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 494e887..94f46f7 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -365,7 +365,7 @@ RESTYPE RT_INPUTCLIENT;
 
 extern XExtensionVersion XIVersion;
 
-Mask PropagateMask[MAXDEVICES];
+Mask PropagateMask[EMASKSIZE];
 
 /*****************************************************************
  *
commit a9c09f8f8e2a97e4bfe927bc4c7f29b04ee3403a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 25 14:24:11 2012 +1000

    dix: fix memory leak in TouchEventHistoryReplay
    
    Don't leak if ti->history is NULL.
    
    Found by coverity.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/dix/touch.c b/dix/touch.c
index 06b15ef..497ad7d 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -463,14 +463,17 @@ TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev)
 void
 TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
 {
-    InternalEvent *tel = InitEventList(GetMaximumEventsNum());
-    ValuatorMask *mask = valuator_mask_new(0);
+    InternalEvent *tel;
+    ValuatorMask *mask;
     int i, nev;
     int flags;
 
     if (!ti->history)
         return;
 
+    tel = InitEventList(GetMaximumEventsNum());
+    mask = valuator_mask_new(0);
+
     valuator_mask_set_double(mask, 0, ti->history[0].valuators.data[0]);
     valuator_mask_set_double(mask, 1, ti->history[0].valuators.data[1]);
 
commit 55ff20eb37f00a3ad07b5acff19d4497ab513a97
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 25 14:22:31 2012 +1000

    dix: fix dereference before null check
    
    Found by Coverity.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/dix/touch.c b/dix/touch.c
index a01f152..06b15ef 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -160,11 +160,13 @@ TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id)
     int i;
     TouchClassPtr t = dev->touch;
     DDXTouchPointInfoPtr ti = NULL;
-    Bool emulate_pointer = (t->mode == XIDirectTouch);
+    Bool emulate_pointer;
 
     if (!t)
         return NULL;
 
+    emulate_pointer = (t->mode == XIDirectTouch);
+
     /* Look for another active touchpoint with the same DDX ID. DDX
      * touchpoints must be unique. */
     if (TouchFindByDDXID(dev, ddx_id, FALSE))
commit e3f47be9fbc489e3eb5832445924810b2ff300f7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Oct 24 10:01:26 2011 +1000

    xfree86: fix use-after-free issue in checkInput
    
    *dev is the condition of the while loop we're in, reset to NULL after
    freeing
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index b22b617..3ec40fe 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -2329,6 +2329,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout)
 
                 current = dev;
                 free(*dev);
+                *dev = NULL;
 
                 do {
                     *current = *(current + 1);
commit 252a69b592001b34714d0fe7508e1898883f9d01
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 20 14:25:54 2012 +1000

    xkb: use local variable instead of casting arg
    
    No functional changes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index fe28e12..082c0db 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -281,12 +281,12 @@ AccessXStickyKeysTurnOff(DeviceIntPtr dev, xkbControlsNotify * pCN)
 static CARD32
 AccessXKRGExpire(OsTimerPtr timer, CARD32 now, pointer arg)
 {
-    XkbSrvInfoPtr xkbi = ((DeviceIntPtr) arg)->key->xkbInfo;
     xkbControlsNotify cn;
+    DeviceIntPtr dev = arg;
+    XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
 
     if (xkbi->krgTimerActive == _KRG_WARN_TIMER) {
-        XkbDDXAccessXBeep((DeviceIntPtr) arg, _BEEP_SLOW_WARN,
-                          XkbStickyKeysMask);
+        XkbDDXAccessXBeep(dev, _BEEP_SLOW_WARN, XkbStickyKeysMask);
         xkbi->krgTimerActive = _KRG_TIMER;
         return 4000;
     }
@@ -296,11 +296,11 @@ AccessXKRGExpire(OsTimerPtr timer, CARD32 now, pointer arg)
     cn.requestMajor = 0;
     cn.requestMinor = 0;
     if (xkbi->desc->ctrls->enabled_ctrls & XkbSlowKeysMask) {
-        AccessXKRGTurnOff((DeviceIntPtr) arg, &cn);
+        AccessXKRGTurnOff(dev, &cn);
         LogMessage(X_INFO, "XKB SlowKeys are disabled.\n");
     }
     else {
-        AccessXKRGTurnOn((DeviceIntPtr) arg, XkbSlowKeysMask, &cn);
+        AccessXKRGTurnOn(dev, XkbSlowKeysMask, &cn);
         LogMessage(X_INFO, "XKB SlowKeys are now enabled. Hold shift to disable.\n");
     }
 
commit d04dfe3f754ad3a5f158057175cbd44319c1ae51
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jun 22 15:18:53 2012 +1000

    Drop custom sigio block/unblock functions from kdrive, ephyr and dmx
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index f734808..2875620 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -227,25 +227,25 @@ dmxCoreMotion(DevicePtr pDev, int x, int y, int delta, DMXBlockType block)
             && pScreen->myNum == dmxScreen->index) {
             /* Screen is old screen */
             if (block)
-                dmxSigioBlock();
+                OsBlockSIGIO();
             if (pDev)
                 enqueueMotion(pDev, localX, localY);
             if (block)
-                dmxSigioUnblock();
+                OsReleaseSIGIO();
         }
         else {
             /* Screen is new */
             DMXDBG4("   New screen: old=%d new=%d localX=%d localY=%d\n",
                     pScreen->myNum, dmxScreen->index, localX, localY);
             if (block)
-                dmxSigioBlock();
+                OsBlockSIGIO();
             mieqProcessInputEvents();
             miPointerSetScreen(inputInfo.pointer, dmxScreen->index,
                                localX, localY);
             if (pDev)
                 enqueueMotion(pDev, localX, localY);
             if (block)
-                dmxSigioUnblock();
+                OsReleaseSIGIO();
         }
 #if 00
         miPointerGetPosition(inputInfo.pointer, &localX, &localY);
@@ -387,12 +387,12 @@ dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     }
 
     if (block)
-        dmxSigioBlock();
+        OsBlockSIGIO();
     valuator_mask_set_range(&mask, firstAxis, axesCount, v);
     QueuePointerEvents(pDevice, MotionNotify, 0, POINTER_ABSOLUTE, &mask);
 
     if (block)
-        dmxSigioUnblock();
+        OsReleaseSIGIO();
 }
 
 static int
@@ -492,10 +492,10 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count,
                                 valuators);
         if (block)
-            dmxSigioBlock();
+            OsBlockSIGIO();
         QueueKeyboardEvents(pDevice, event, ke->keycode, &mask);
         if (block)
-            dmxSigioUnblock();
+            OsReleaseSIGIO();
         break;
     case XI_DeviceButtonPress:
     case XI_DeviceButtonRelease:
@@ -503,11 +503,11 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count,
                                 valuators);
         if (block)
-            dmxSigioBlock();
+            OsBlockSIGIO();
         QueuePointerEvents(pDevice, event, ke->keycode,
                            POINTER_ABSOLUTE, &mask);
         if (block)
-            dmxSigioUnblock();
+            OsReleaseSIGIO();
         break;
     case XI_ProximityIn:
     case XI_ProximityOut:
@@ -515,10 +515,10 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count,
                                 valuators);
         if (block)
-            dmxSigioBlock();
+            OsBlockSIGIO();
         QueueProximityEvents(pDevice, event, &mask);
         if (block)
-            dmxSigioUnblock();
+            OsReleaseSIGIO();
         break;
 
         break;
diff --git a/hw/dmx/input/dmxsigio.c b/hw/dmx/input/dmxsigio.c
index 9b1b493..6ef543c 100644
--- a/hw/dmx/input/dmxsigio.c
+++ b/hw/dmx/input/dmxsigio.c
@@ -84,28 +84,6 @@ dmxSigioHandler(int sig)
     }
 }
 
-/** Block SIGIO handling. */
-void
-dmxSigioBlock(void)
-{
-    sigset_t s;
-
-    sigemptyset(&s);
-    sigaddset(&s, SIGIO);
-    sigprocmask(SIG_BLOCK, &s, 0);
-}
-
-/** Unblock SIGIO handling. */
-void
-dmxSigioUnblock(void)
-{
-    sigset_t s;
-
-    sigemptyset(&s);
-    sigaddset(&s, SIGIO);
-    sigprocmask(SIG_UNBLOCK, &s, 0);
-}
-
 static void
 dmxSigioHook(void)
 {
diff --git a/hw/dmx/input/dmxsigio.h b/hw/dmx/input/dmxsigio.h
index 4e48749..9f30662 100644
--- a/hw/dmx/input/dmxsigio.h
+++ b/hw/dmx/input/dmxsigio.h
@@ -36,8 +36,6 @@
 
 #ifndef _DMXSIGIO_H_
 #define _DMXSIGIO_H_
-extern void dmxSigioBlock(void);
-extern void dmxSigioUnblock(void);
 extern void dmxSigioEnableInput(void);
 extern void dmxSigioDisableInput(void);
 extern void dmxSigioRegister(DMXInputInfo * dmxInput, int fd);
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 8eda539..fe3dae6 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -772,26 +772,6 @@ ephyrUpdateModifierState(unsigned int state)
     }
 }
 
-static void
-ephyrBlockSigio(void)
-{
-    sigset_t set;
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGIO);
-    sigprocmask(SIG_BLOCK, &set, 0);
-}
-
-static void
-ephyrUnblockSigio(void)
-{
-    sigset_t set;
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGIO);
-    sigprocmask(SIG_UNBLOCK, &set, 0);
-}
-
 static Bool
 ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
 {
@@ -808,11 +788,11 @@ int ephyrCurScreen;             /*current event screen */
 static void
 ephyrWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 {
-    ephyrBlockSigio();
+    OsBlockSIGIO();
     ephyrCurScreen = pScreen->myNum;
     miPointerWarpCursor(inputInfo.pointer, pScreen, x, y);
 
-    ephyrUnblockSigio();
+    OsReleaseSIGIO();
 }
 
 miPointerScreenFuncRec ephyrPointerScreenFuncs = {
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 58ae552..000bda9 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -102,26 +102,6 @@ KdSigio(int sig)
         (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
 }
 
-static void
-KdBlockSigio(void)
-{
-    sigset_t set;
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGIO);
-    sigprocmask(SIG_BLOCK, &set, 0);
-}
-
-static void
-KdUnblockSigio(void)
-{
-    sigset_t set;
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGIO);
-    sigprocmask(SIG_UNBLOCK, &set, 0);
-}
-
 #ifdef DEBUG_SIGIO
 
 void
@@ -261,7 +241,7 @@ KdDisableInput(void)
     KdPointerInfo *pi;
     int found = 0, i = 0;
 
-    KdBlockSigio();
+    OsBlockSIGIO();
 
     for (ki = kdKeyboards; ki; ki = ki->next) {
         if (ki->driver && ki->driver->Disable)
@@ -343,7 +323,7 @@ KdEnableInput(void)
     NoticeEventTime(&ev, pi->dixdev);
     NoticeEventTime(&ev, ki->dixdev);
 
-    KdUnblockSigio();
+    OsReleaseSIGIO();
 }
 
 static KdKeyboardDriver *
@@ -1801,7 +1781,7 @@ KdReleaseAllKeys(void)
     int key;
     KdKeyboardInfo *ki;
 
-    KdBlockSigio();
+    OsBlockSIGIO();
 
     for (ki = kdKeyboards; ki; ki = ki->next) {
         for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; key++) {
@@ -1812,7 +1792,7 @@ KdReleaseAllKeys(void)
         }
     }
 
-    KdUnblockSigio();
+    OsReleaseSIGIO();
 #endif
 }
 
@@ -2009,18 +1989,18 @@ KdWakeupHandler(ScreenPtr pScreen,
     if (kdInputEnabled && result > 0) {
         for (i = 0; i < kdNumInputFds; i++)
             if (FD_ISSET(kdInputFds[i].fd, pReadmask)) {
-                KdBlockSigio();
+                OsBlockSIGIO();
                 (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
-                KdUnblockSigio();
+                OsReleaseSIGIO();
             }
     }
     for (pi = kdPointers; pi; pi = pi->next) {
         if (pi->timeoutPending) {
             if ((long) (GetTimeInMillis() - pi->emulationTimeout) >= 0) {
                 pi->timeoutPending = FALSE;
-                KdBlockSigio();
+                OsBlockSIGIO();
                 KdReceiveTimeout(pi);
-                KdUnblockSigio();
+                OsReleaseSIGIO();
             }
         }
     }
@@ -2117,10 +2097,10 @@ int KdCurScreen;                /* current event screen */
 static void
 KdWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 {
-    KdBlockSigio();
+    OsBlockSIGIO();
     KdCurScreen = pScreen->myNum;
     miPointerWarpCursor(pDev, pScreen, x, y);
-    KdUnblockSigio();
+    OsReleaseSIGIO();
 }
 
 miPointerScreenFuncRec kdPointerScreenFuncs = {
commit 5d309af2ed93e91c7d72f548a11052051efbb40f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jun 22 14:56:25 2012 +1000

    xfree86: drop ddx-specific SIGIO blocking
    
    The hooks are left for this cycle, we can drop it next cycle once the
    drivers that need it (e.g. wacom) have been updated.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Cursor.c b/hw/xfree86/common/xf86Cursor.c
index c01cfd1..65a9e82 100644
--- a/hw/xfree86/common/xf86Cursor.c
+++ b/hw/xfree86/common/xf86Cursor.c
@@ -199,7 +199,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
     ScrnInfoPtr pScr = xf86ScreenToScrn(pScreen);
     ScreenPtr pCursorScreen;
     Bool Switched;
-    int px, py, was_blocked;
+    int px, py;
     DeviceIntPtr dev, it;
 
     if (!pScr->vtSema || !mode || !pScr->SwitchMode)
@@ -228,7 +228,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
     if (pScreen == pCursorScreen)
         miPointerGetPosition(dev, &px, &py);
 
-    was_blocked = xf86BlockSIGIO();
+    OsBlockSIGIO();
     Switched = (*pScr->SwitchMode) (pScr, mode);
     if (Switched) {
         pScr->currentMode = mode;
@@ -267,7 +267,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
             pScr->frameY1 = pScr->virtualY - 1;
         }
     }
-    xf86UnblockSIGIO(was_blocked);
+    OsReleaseSIGIO();
 
     if (pScr->AdjustFrame)
         (*pScr->AdjustFrame) (pScr, pScr->frameX0, pScr->frameY0);
@@ -469,13 +469,11 @@ xf86CrossScreen(ScreenPtr pScreen, Bool entering)
 static void
 xf86WarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 {
-    int sigstate;
-
-    sigstate = xf86BlockSIGIO();
+    OsBlockSIGIO();
     miPointerWarpCursor(pDev, pScreen, x, y);
 
     xf86Info.currentScreen = pScreen;
-    xf86UnblockSIGIO(sigstate);
+    OsReleaseSIGIO();
 }
 
 void *
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 4fcad40..47429ec 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -254,7 +254,7 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask)
             while (pInfo) {
                 if (pInfo->read_input && pInfo->fd >= 0 &&
                     (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
-                    int sigstate = xf86BlockSIGIO();
+                    OsBlockSIGIO();
 
                     /*
                      * Remove the descriptior from the set because more than one
@@ -263,7 +263,7 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask)
                     FD_CLR(pInfo->fd, &devicesWithInput);
 
                     pInfo->read_input(pInfo);
-                    xf86UnblockSIGIO(sigstate);
+                    OsReleaseSIGIO();
                 }
                 pInfo = pInfo->next;
             }
@@ -397,9 +397,9 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
     for (i = keyc->xkbInfo->desc->min_key_code;
          i < keyc->xkbInfo->desc->max_key_code; i++) {
         if (key_is_down(pDev, i, KEY_POSTED)) {
-            sigstate = xf86BlockSIGIO();
+            OsBlockSIGIO();
             QueueKeyboardEvents(pDev, KeyRelease, i, NULL);
-            xf86UnblockSIGIO(sigstate);
+            OsReleaseSIGIO();
         }
     }
 }
@@ -457,7 +457,7 @@ xf86VTSwitch(void)
             }
         }
 
-        prevSIGIO = xf86BlockSIGIO();
+        OsBlockSIGIO();
         for (i = 0; i < xf86NumScreens; i++)
             xf86Screens[i]->LeaveVT(xf86Screens[i]);
 
@@ -492,7 +492,7 @@ xf86VTSwitch(void)
             for (ih = InputHandlers; ih; ih = ih->next)
                 xf86EnableInputHandler(ih);
 
-            xf86UnblockSIGIO(prevSIGIO);
+            OsReleaseSIGIO();
 
         }
         else {
@@ -549,7 +549,7 @@ xf86VTSwitch(void)
         for (ih = InputHandlers; ih; ih = ih->next)
             xf86EnableInputHandler(ih);
 
-        xf86UnblockSIGIO(prevSIGIO);
+        OsReleaseSIGIO();
     }
 }
 
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 526b95d..0f8f810 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -394,7 +394,7 @@ InstallSignalHandlers(void)
 void
 InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
 {
-    int i, j, k, scr_index, was_blocked = 0;
+    int i, j, k, scr_index;
     char **modulelist;
     pointer *optionlist;
     Pix24Flags screenpix24, pix24;
@@ -806,7 +806,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
             ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
 #endif
             xf86AccessEnter();
-            was_blocked = xf86BlockSIGIO();
+            OsBlockSIGIO();
         }
     }
 
@@ -879,7 +879,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
     }
 
     xf86VGAarbiterWrapFunctions();
-    xf86UnblockSIGIO(was_blocked);
+    OsReleaseSIGIO();
 
     xf86InitOrigins();
 
@@ -964,7 +964,7 @@ OsVendorInit(void)
     }
 #endif
 #endif
-    xf86UnblockSIGIO(0);
+    OsReleaseSIGIO();
 
     beenHere = TRUE;
 }
@@ -1023,7 +1023,7 @@ AbortDDX(enum ExitCode error)
 {
     int i;
 
-    xf86BlockSIGIO();
+    OsBlockSIGIO();
 
     /*
      * try to restore the original video state
diff --git a/hw/xfree86/common/xf86PM.c b/hw/xfree86/common/xf86PM.c
index 1830640..15257cb 100644
--- a/hw/xfree86/common/xf86PM.c
+++ b/hw/xfree86/common/xf86PM.c
@@ -92,8 +92,6 @@ eventName(pmEvent event, const char **str)
     }
 }
 
-static int sigio_blocked_for_suspend;
-
 static void
 suspend(pmEvent event, Bool undo)
 {
@@ -109,7 +107,7 @@ suspend(pmEvent event, Bool undo)
         DisableDevice(pInfo->dev, TRUE);
         pInfo = pInfo->next;
     }
-    sigio_blocked_for_suspend = xf86BlockSIGIO();
+    OsBlockSIGIO();
     for (i = 0; i < xf86NumScreens; i++) {
         if (xf86Screens[i]->PMEvent)
             xf86Screens[i]->PMEvent(xf86Screens[i], event, undo);
@@ -137,7 +135,7 @@ resume(pmEvent event, Bool undo)
             xf86Screens[i]->EnterVT(xf86Screens[i]);
         }
     }
-    xf86UnblockSIGIO(sigio_blocked_for_suspend);
+    OsReleaseSIGIO();
     for (i = 0; i < xf86NumScreens; i++) {
         if (xf86Screens[i]->EnableDisableFBAccess)
             (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
@@ -153,7 +151,7 @@ resume(pmEvent event, Bool undo)
 static void
 DoApmEvent(pmEvent event, Bool undo)
 {
-    int i, was_blocked;
+    int i;
 
     switch (event) {
 #if 0
@@ -184,13 +182,13 @@ DoApmEvent(pmEvent event, Bool undo)
         }
         break;
     default:
-        was_blocked = xf86BlockSIGIO();
+        OsBlockSIGIO();
         for (i = 0; i < xf86NumScreens; i++) {
             if (xf86Screens[i]->PMEvent) {
                 xf86Screens[i]->PMEvent(xf86Screens[i], event, undo);
             }
         }
-        xf86UnblockSIGIO(was_blocked);
+        OsReleaseSIGIO();
         break;
     }
 }
diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c
index e9c1c0e..696a215 100644
--- a/hw/xfree86/os-support/shared/sigio.c
+++ b/hw/xfree86/os-support/shared/sigio.c
@@ -132,7 +132,6 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
     struct sigaction sa;
     struct sigaction osa;
     int i;
-    int blocked;
     int installed = FALSE;
 
     if (!xf86Info.useSIGIO)
@@ -142,7 +141,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
         if (!xf86SigIOFuncs[i].f) {
             if (xf86IsPipe(fd))
                 return 0;
-            blocked = xf86BlockSIGIO();
+            OsBlockSIGIO();
 #ifdef O_ASYNC
             if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC) == -1) {
                 xf86Msg(X_WARNING, "fcntl(%d, O_ASYNC): %s\n",
@@ -170,7 +169,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
             }
 #endif
             if (!installed) {
-                xf86UnblockSIGIO(blocked);
+                OsReleaseSIGIO();
                 return 0;
             }
             sigemptyset(&sa.sa_mask);
@@ -186,7 +185,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
             if (fd >= xf86SigIOMaxFd)
                 xf86SigIOMaxFd = fd + 1;
             FD_SET(fd, &xf86SigIOMask);
-            xf86UnblockSIGIO(blocked);
+            OsReleaseSIGIO();
             return 1;
         }
         /* Allow overwriting of the closure and callback */
commit ff67135bec3ecea8cebeb46b42ece0a6671e231d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jun 22 13:09:35 2012 +1000

    xfree86: use OsBlockSIGIO from the ddx
    
    We can ignore the "wasset" argument now since the DIX will keep proper
    refcounting.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c
index 12ae8a4..e9c1c0e 100644
--- a/hw/xfree86/os-support/shared/sigio.c
+++ b/hw/xfree86/os-support/shared/sigio.c
@@ -259,26 +259,13 @@ xf86RemoveSIGIOHandler(int fd)
 int
 xf86BlockSIGIO(void)
 {
-    sigset_t set, old;
-    int ret;
-
-    sigemptyset(&set);
-    sigaddset(&set, SIGIO);
-    sigprocmask(SIG_BLOCK, &set, &old);
-    ret = sigismember(&old, SIGIO);
-    return ret;
+    return OsBlockSIGIO();
 }
 
 void
 xf86UnblockSIGIO(int wasset)
 {
-    sigset_t set;
-
-    if (!wasset) {
-        sigemptyset(&set);
-        sigaddset(&set, SIGIO);
-        sigprocmask(SIG_UNBLOCK, &set, NULL);
-    }
+    OsReleaseSIGIO();
 }
 
 void
commit 6bf356ef2831baeccd7a650ed3fde0831e33c6c0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jun 22 13:02:40 2012 +1000

    os: add OsBlockSIGIO and OsReleaseSIGIO
    
    Let the dix be in charge of changing the sigprocmask so we only have one
    entity that changes it.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/include/os.h b/include/os.h
index 276eb52..8540b82 100644
--- a/include/os.h
+++ b/include/os.h
@@ -333,6 +333,12 @@ OsBlockSignals(void);
 extern _X_EXPORT void
 OsReleaseSignals(void);
 
+extern _X_EXPORT int
+OsBlockSIGIO(void);
+
+extern _X_EXPORT void
+OsReleaseSIGIO(void);
+
 extern _X_EXPORT void
 OsAbort(void)
     _X_NORETURN;
diff --git a/os/utils.c b/os/utils.c
index 3a1ef93..55f58b9 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1165,15 +1165,15 @@ OsBlockSignals(void)
     if (BlockedSignalCount++ == 0) {
         sigset_t set;
 
+#ifdef SIGIO
+        OsBlockSIGIO();
+#endif
         sigemptyset(&set);
         sigaddset(&set, SIGALRM);
         sigaddset(&set, SIGVTALRM);
 #ifdef SIGWINCH
         sigaddset(&set, SIGWINCH);
 #endif
-#ifdef SIGIO
-        sigaddset(&set, SIGIO);
-#endif
         sigaddset(&set, SIGTSTP);
         sigaddset(&set, SIGTTIN);
         sigaddset(&set, SIGTTOU);
@@ -1183,12 +1183,60 @@ OsBlockSignals(void)
 #endif
 }
 
+#ifdef SIG_BLOCK
+static sig_atomic_t sigio_blocked;
+#endif
+
+/**
+ * returns zero if this call caused SIGIO to be blocked now, non-zero if it
+ * was already blocked by a previous call to this function.
+ */
+int
+OsBlockSIGIO(void)
+{
+#ifdef SIGIO
+#ifdef SIG_BLOCK
+    if (sigio_blocked++ == 0) {
+        sigset_t set, old;
+        int ret;
+
+        sigemptyset(&set);
+        sigaddset(&set, SIGIO);
+        sigprocmask(SIG_BLOCK, &set, &old);
+        ret = sigismember(&old, SIGIO);
+        return ret;
+    } else
+        return 1;
+#endif
+#endif
+}
+
+void
+OsReleaseSIGIO(void)
+{
+#ifdef SIGIO
+#ifdef SIG_BLOCK
+    if (--sigio_blocked == 0) {
+        sigset_t set;
+
+        sigemptyset(&set);
+        sigaddset(&set, SIGIO);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    } else if (sigio_blocked < 0) {
+        BUG_WARN(sigio_blocked < 0);
+        sigio_blocked = 0;
+    }
+#endif
+#endif
+}
+
 void
 OsReleaseSignals(void)
 {
 #ifdef SIG_BLOCK
     if (--BlockedSignalCount == 0) {
         sigprocmask(SIG_SETMASK, &PreviousSignalMask, 0);
+        OsReleaseSIGIO();
     }
 #endif
 }
diff --git a/test/Makefile.am b/test/Makefile.am
index b2a53aa..436351c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -5,7 +5,7 @@ if XORG
 # Tests that require at least some DDX functions in order to fully link
 # For now, requires xf86 ddx, could be adjusted to use another
 SUBDIRS += xi2
-noinst_PROGRAMS += xkb input xtest misc fixes xfree86  hashtabletest
+noinst_PROGRAMS += xkb input xtest misc fixes xfree86  hashtabletest os
 endif
 check_LTLIBRARIES = libxservertest.la
 
@@ -37,6 +37,7 @@ fixes_LDADD=$(TEST_LDADD)
 xfree86_LDADD=$(TEST_LDADD)
 touch_LDADD=$(TEST_LDADD)
 hashtabletest_LDADD=$(TEST_LDADD) $(top_srcdir)/Xext/hashtable.c
+os_LDADD=$(TEST_LDADD)
 
 libxservertest_la_LIBADD = $(XSERVER_LIBS)
 if XORG
diff --git a/test/os.c b/test/os.c
new file mode 100644
index 0000000..1460a34
--- /dev/null
+++ b/test/os.c
@@ -0,0 +1,130 @@
+/**
+ * Copyright © 2012 Red Hat, Inc.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),
+ *  to deal in the Software without restriction, including without limitation
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice (including the next
+ *  paragraph) shall be included in all copies or substantial portions of the
+ *  Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <signal.h>
+#include "os.h"
+
+static int
+sig_is_blocked(int sig)
+{
+    sigset_t current;
+
+    sigemptyset(&current);
+    assert(sigprocmask(SIG_BLOCK, NULL, &current) == 0);
+    return sigismember(&current, sig);
+}
+
+static void block_sigio_test(void)
+{
+#ifdef SIG_BLOCK
+    sigset_t current;
+
+    sigemptyset(&current);
+    assert(!sig_is_blocked(SIGIO));
+
+    /* block once */
+    OsBlockSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSIGIO();
+    assert(!sig_is_blocked(SIGIO));
+
+    /* block twice, nested */
+    OsBlockSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsBlockSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSIGIO();
+    assert(!sig_is_blocked(SIGIO));
+
+    /* block all */
+    OsBlockSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSignals();
+    assert(!sig_is_blocked(SIGIO));
+
+    /* block all nested */
+    OsBlockSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsBlockSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSignals();
+    assert(!sig_is_blocked(SIGIO));
+
+    /* mix the two */
+    /* ABBA */
+    OsBlockSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsBlockSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSignals();
+    assert(!sig_is_blocked(SIGIO));
+
+    /* ABAB */
+    OsBlockSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsBlockSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSIGIO();
+    assert(!sig_is_blocked(SIGIO));
+
+    /* BAAB */
+    OsBlockSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsBlockSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSIGIO();
+    assert(!sig_is_blocked(SIGIO));
+
+    /* BABA */
+    OsBlockSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsBlockSignals();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSIGIO();
+    assert(sig_is_blocked(SIGIO));
+    OsReleaseSignals();
+    assert(!sig_is_blocked(SIGIO));
+
+#endif
+}
+
+int
+main(int argc, char **argv)
+{
+    block_sigio_test();
+    return 0;
+}
commit 9f1edced9abc066f0ba47672d006fe50fb206371
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jun 15 10:00:51 2012 +1000

    xfree86: always enable SIGIO on OsVendorInit (#50957)
    
    Drivers call xf86InstallSIGIOHandler() for their fd on DEVICE_ON. That
    function does not actually enable the signal if it was blocked to begin
    with. As a result, if one vt-switches away from the server (SIGIO is
    blocked) and then triggers a server regeneration, the signal remains
    blocked and input devices are dead.
    
    Avoid this by always unblocking SIGIO when we start the server.
    
    X.Org Bug 50957 <http://bugs.freedesktop.org/show_bug.cgi?id=50957>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index ca6efd4..526b95d 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -964,6 +964,7 @@ OsVendorInit(void)
     }
 #endif
 #endif
+    xf86UnblockSIGIO(0);
 
     beenHere = TRUE;
 }


More information about the xorg-commit mailing list