xserver: Branch 'master' - 16 commits

Adam Jackson ajax at kemper.freedesktop.org
Tue Dec 1 10:56:47 PST 2015


 Xext/xselinux_hooks.c                   |   18 --
 config/dbus-core.c                      |   16 --
 config/udev.c                           |   45 ++----
 configure.ac                            |    2 
 dix/dispatch.c                          |   17 +-
 dix/dixfonts.c                          |    2 
 dix/main.c                              |    3 
 hw/kdrive/ephyr/ephyr.c                 |    6 
 hw/kdrive/ephyr/ephyr.h                 |    3 
 hw/kdrive/ephyr/hostx.c                 |    6 
 hw/kdrive/ephyr/hostx.h                 |    2 
 hw/kdrive/ephyr/os.c                    |    1 
 hw/kdrive/linux/linux.c                 |   17 --
 hw/kdrive/src/kinput.c                  |   28 +--
 hw/xfree86/common/xf86Events.c          |   67 +++------
 hw/xfree86/drivers/modesetting/vblank.c |   16 --
 hw/xwayland/xwayland.c                  |   19 +-
 include/dix-config.h.in                 |    3 
 include/dixstruct.h                     |    6 
 include/os.h                            |   16 +-
 os/WaitFor.c                            |   50 +++----
 os/connection.c                         |  225 ++++++++++++++++++++++----------
 os/io.c                                 |   21 --
 os/osdep.h                              |   10 +
 os/osinit.c                             |    1 
 os/utils.c                              |   38 ++---
 os/xdmcp.c                              |  114 +++++-----------
 render/animcur.c                        |   57 ++++----
 28 files changed, 419 insertions(+), 390 deletions(-)

New commits:
commit 7b02f0b87ec2fa0cc5a65307a1fd55c671cec884
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:17 2015 -0800

    os: Use NotifyFd interface for listen descriptors
    
    Replace the custom path for dealing with new incoming connections with
    the general-purpose NotifyFd API.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/os.h b/include/os.h
index aed2e2f..e7c1936 100644
--- a/include/os.h
+++ b/include/os.h
@@ -139,9 +139,6 @@ extern _X_EXPORT const char *ClientAuthorized(ClientPtr /*client */ ,
                                               unsigned int /*string_n */ ,
                                               char * /*auth_string */ );
 
-extern _X_EXPORT Bool EstablishNewConnections(ClientPtr clientUnused,
-                                              void *closure);
-
 extern _X_EXPORT void CheckConnections(void);
 
 extern _X_EXPORT void CloseDownConnection(ClientPtr /*client */ );
diff --git a/os/WaitFor.c b/os/WaitFor.c
index b579e1b..e839d61 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -311,10 +311,6 @@ WaitForSomething(int *pClientsReady)
 
             XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices);
             XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
-            XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections);
-            if (XFD_ANYSET(&tmp_set))
-                QueueWorkProc(EstablishNewConnections, NULL,
-                              (void *) &LastSelectMask);
 
             XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
             if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
diff --git a/os/connection.c b/os/connection.c
index 4da01a6..8d866f6 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -121,7 +121,6 @@ SOFTWARE.
 
 static int lastfdesc;           /* maximum file descriptor */
 
-fd_set WellKnownConnections;    /* Listener mask */
 fd_set EnabledDevices;          /* mask for input devices that are on */
 fd_set NotifyReadFds;           /* mask for other file descriptors */
 fd_set NotifyWriteFds;          /* mask for other write file descriptors */
@@ -154,6 +153,9 @@ static fd_set SavedAllSockets;
 static fd_set SavedClientsWithInput;
 int GrabInProgress = 0;
 
+static void
+QueueNewConnections(int curconn, int ready, void *data);
+
 #if !defined(WIN32)
 int *ConnectionTranslation = NULL;
 #else
@@ -403,8 +405,6 @@ CreateWellKnownSockets(void)
     ClearConnectionTranslation();
 #endif
 
-    FD_ZERO(&WellKnownConnections);
-
     /* display is initialized to "0" by main(). It is then set to the display
      * number if specified on the command line. */
 
@@ -441,13 +441,13 @@ CreateWellKnownSockets(void)
         int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
 
         ListenTransFds[i] = fd;
-        FD_SET(fd, &WellKnownConnections);
+        SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL);
 
         if (!_XSERVTransIsLocal(ListenTransConns[i]))
             DefineSelf (fd);
     }
 
-    if (!XFD_ANYSET(&WellKnownConnections) && !NoListenAll)
+    if (ListenTransCount == 0 && !NoListenAll)
         FatalError
             ("Cannot establish any listening sockets - Make sure an X server isn't already running");
 
@@ -457,7 +457,6 @@ CreateWellKnownSockets(void)
 #endif
     OsSignal(SIGINT, GiveUp);
     OsSignal(SIGTERM, GiveUp);
-    XFD_COPYSET(&WellKnownConnections, &AllSockets);
     ResetHosts(display);
 
     InitParentProcess();
@@ -484,7 +483,7 @@ ResetWellKnownSockets(void)
                  * Remove it from out list.
                  */
 
-                FD_CLR(ListenTransFds[i], &WellKnownConnections);
+                RemoveNotifyFd(ListenTransFds[i]);
                 ListenTransFds[i] = ListenTransFds[ListenTransCount - 1];
                 ListenTransConns[i] = ListenTransConns[ListenTransCount - 1];
                 ListenTransCount -= 1;
@@ -497,12 +496,12 @@ ResetWellKnownSockets(void)
 
                 int newfd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
 
-                FD_CLR(ListenTransFds[i], &WellKnownConnections);
                 ListenTransFds[i] = newfd;
-                FD_SET(newfd, &WellKnownConnections);
             }
         }
     }
+    for (i = 0; i < ListenTransCount; i++)
+        SetNotifyFd(ListenTransFds[i], QueueNewConnections, X_NOTIFY_READ, NULL);
 
     ResetAuthorization();
     ResetHosts(display);
@@ -523,6 +522,7 @@ CloseWellKnownConnections(void)
         if (ListenTransConns[i] != NULL) {
             _XSERVTransClose(ListenTransConns[i]);
             ListenTransConns[i] = NULL;
+            RemoveNotifyFd(ListenTransFds[i]);
         }
     }
     ListenTransCount = 0;
@@ -810,22 +810,18 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time)
  *    and AllSockets.
  *****************/
 
- /*ARGSUSED*/ Bool
+static Bool
 EstablishNewConnections(ClientPtr clientUnused, void *closure)
 {
-    fd_set readyconnections;    /* set of listeners that are ready */
-    int curconn;                /* fd of listener that's ready */
-    register int newconn;       /* fd of new client */
+    int curconn = (int) (intptr_t) closure;
+    int newconn;       /* fd of new client */
     CARD32 connect_time;
-    register int i;
-    register ClientPtr client;
-    register OsCommPtr oc;
-    fd_set tmask;
+    int i;
+    ClientPtr client;
+    OsCommPtr oc;
+    XtransConnInfo trans_conn, new_trans_conn;
+    int status;
 
-    XFD_ANDSET(&tmask, (fd_set *) closure, &WellKnownConnections);
-    XFD_COPYSET(&tmask, &readyconnections);
-    if (!XFD_ANYSET(&readyconnections))
-        return TRUE;
     connect_time = GetTimeInMillis();
     /* kill off stragglers */
     for (i = 1; i < currentMaxClients; i++) {
@@ -837,58 +833,43 @@ EstablishNewConnections(ClientPtr clientUnused, void *closure)
                 CloseDownClient(client);
         }
     }
-#ifndef WIN32
-    for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) {
-        while (readyconnections.fds_bits[i])
-#else
-    for (i = 0; i < XFD_SETCOUNT(&readyconnections); i++)
-#endif
-    {
-        XtransConnInfo trans_conn, new_trans_conn;
-        int status;
 
-#ifndef WIN32
-        curconn = mffs(readyconnections.fds_bits[i]) - 1;
-        readyconnections.fds_bits[i] &= ~((fd_mask) 1 << curconn);
-        curconn += (i * (sizeof(fd_mask) * 8));
-#else
-        curconn = XFD_FD(&readyconnections, i);
-#endif
-
-        if ((trans_conn = lookup_trans_conn(curconn)) == NULL)
-            continue;
+    if ((trans_conn = lookup_trans_conn(curconn)) == NULL)
+        return TRUE;
 
-        if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL)
-            continue;
+    if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL)
+        return TRUE;
 
-        newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
+    newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
 
-        if (newconn < lastfdesc) {
-            int clientid;
+    if (newconn < lastfdesc) {
+        int clientid;
 
 #if !defined(WIN32)
-            clientid = ConnectionTranslation[newconn];
+        clientid = ConnectionTranslation[newconn];
 #else
-            clientid = GetConnectionTranslation(newconn);
+        clientid = GetConnectionTranslation(newconn);
 #endif
-            if (clientid && (client = clients[clientid]))
-                CloseDownClient(client);
-        }
+        if (clientid && (client = clients[clientid]))
+            CloseDownClient(client);
+    }
 
-        _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
+    _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
 
-        if (trans_conn->flags & TRANS_NOXAUTH)
-            new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
+    if (trans_conn->flags & TRANS_NOXAUTH)
+        new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
 
-        if (!AllocNewConnection(new_trans_conn, newconn, connect_time)) {
-            ErrorConnMax(new_trans_conn);
-            _XSERVTransClose(new_trans_conn);
-        }
+    if (!AllocNewConnection(new_trans_conn, newconn, connect_time)) {
+        ErrorConnMax(new_trans_conn);
+        _XSERVTransClose(new_trans_conn);
     }
-#ifndef WIN32
+    return TRUE;
 }
-#endif
-return TRUE;
+
+static void
+QueueNewConnections(int fd, int ready, void *data)
+{
+    QueueWorkProc(EstablishNewConnections, NULL, (void *) (intptr_t) fd);
 }
 
 #define NOROOM "Maximum number of clients reached"
@@ -1417,8 +1398,7 @@ ListenOnOpenFD(int fd, int noxauth)
     ListenTransConns[ListenTransCount] = ciptr;
     ListenTransFds[ListenTransCount] = fd;
 
-    FD_SET(fd, &WellKnownConnections);
-    FD_SET(fd, &AllSockets);
+    SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL);
 
     /* Increment the count */
     ListenTransCount++;
commit 1df07dc36ca145c59f51176d9ab2651112506d75
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:16 2015 -0800

    hw/xfree86: Use NotifyFd for device and other input fd wakeups
    
    Remove code in xf86Wakeup for dealing with device and other input and
    switch to using the new NotifyFd interface.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 709afd6..2db6e5b 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -101,8 +101,6 @@ Bool VTSwitchEnabled = TRUE;    /* Allows run-time disabling for
                                  switches when using the DRI
                                  automatic full screen mode.*/
 
-extern fd_set EnabledDevices;
-
 #ifdef XF86PM
 extern void (*xf86OSPMClose) (void);
 #endif
@@ -247,45 +245,6 @@ xf86ProcessActionEvent(ActionEvent action, void *arg)
 void
 xf86Wakeup(void *blockData, int err, void *pReadmask)
 {
-    fd_set *LastSelectMask = (fd_set *) pReadmask;
-    fd_set devicesWithInput;
-    InputInfoPtr pInfo;
-
-    if (err >= 0) {
-
-        XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices);
-        if (XFD_ANYSET(&devicesWithInput)) {
-            pInfo = xf86InputDevs;
-            while (pInfo) {
-                if (pInfo->read_input && pInfo->fd >= 0 &&
-                    (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
-                    OsBlockSIGIO();
-
-                    /*
-                     * Remove the descriptior from the set because more than one
-                     * device may share the same file descriptor.
-                     */
-                    FD_CLR(pInfo->fd, &devicesWithInput);
-
-                    pInfo->read_input(pInfo);
-                    OsReleaseSIGIO();
-                }
-                pInfo = pInfo->next;
-            }
-        }
-    }
-
-    if (err >= 0) {             /* we don't want the handlers called if select() */
-        IHPtr ih, ih_tmp;       /* returned with an error condition, do we?      */
-
-        nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) {
-            if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
-                (FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) {
-                ih->ihproc(ih->fd, ih->data);
-            }
-        }
-    }
-
     if (xf86VTSwitchPending())
         xf86VTSwitch();
 }
@@ -305,6 +264,15 @@ xf86SigioReadInput(int fd, void *closure)
     errno = errno_save;
 }
 
+static void
+xf86NotifyReadInput(int fd, int ready, void *closure)
+{
+    InputInfoPtr pInfo = closure;
+    OsBlockSIGIO();
+    pInfo->read_input(pInfo);
+    OsReleaseSIGIO();
+}
+
 /*
  * xf86AddEnabledDevice --
  *
@@ -314,6 +282,7 @@ xf86AddEnabledDevice(InputInfoPtr pInfo)
 {
     if (!xf86InstallSIGIOHandler(pInfo->fd, xf86SigioReadInput, pInfo)) {
         AddEnabledDevice(pInfo->fd);
+        SetNotifyFd(pInfo->fd, xf86NotifyReadInput, X_NOTIFY_READ, pInfo);
     }
 }
 
@@ -326,6 +295,7 @@ xf86RemoveEnabledDevice(InputInfoPtr pInfo)
 {
     if (!xf86RemoveSIGIOHandler(pInfo->fd)) {
         RemoveEnabledDevice(pInfo->fd);
+        RemoveNotifyFd(pInfo->fd);
     }
 }
 
@@ -636,6 +606,16 @@ xf86VTSwitch(void)
 
 /* Input handler registration */
 
+static void
+xf86InputHandlerNotify(int fd, int ready, void *data)
+{
+    IHPtr       ih = data;
+
+    if (ih->enabled && ih->fd >= 0 && ih->ihproc) {
+        ih->ihproc(ih->fd, ih->data);
+    }
+}
+
 static void *
 addInputHandler(int fd, InputHandlerProc proc, void *data)
 {
@@ -653,6 +633,11 @@ addInputHandler(int fd, InputHandlerProc proc, void *data)
     ih->data = data;
     ih->enabled = TRUE;
 
+    if (!SetNotifyFd(fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih)) {
+        free(ih);
+        return NULL;
+    }
+
     ih->next = InputHandlers;
     InputHandlers = ih;
 
commit e51ea53b26bd9ec05b9209825960af28d0b6bbe1
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:15 2015 -0800

    render: Use OsTimer for animated cursor timing
    
    This replaces the block/wakeup handlers with an OsTimer. This also
    avoids problems with performing rendering during the wakeup handler.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/render/animcur.c b/render/animcur.c
index 825ae1f..52e6b8b 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -59,15 +59,14 @@ typedef struct _AnimCur {
 
 typedef struct _AnimScrPriv {
     CloseScreenProcPtr CloseScreen;
-
-    ScreenBlockHandlerProcPtr BlockHandler;
-
     CursorLimitsProcPtr CursorLimits;
     DisplayCursorProcPtr DisplayCursor;
     SetCursorPositionProcPtr SetCursorPosition;
     RealizeCursorProcPtr RealizeCursor;
     UnrealizeCursorProcPtr UnrealizeCursor;
     RecolorCursorProcPtr RecolorCursor;
+    OsTimerPtr timer;
+    Bool timer_set;
 } AnimCurScreenRec, *AnimCurScreenPtr;
 
 static unsigned char empty[4];
@@ -129,28 +128,23 @@ AnimCurCursorLimits(DeviceIntPtr pDev,
 }
 
 /*
- * This has to be a screen block handler instead of a generic
- * block handler so that it is well ordered with respect to the DRI
- * block handler responsible for releasing the hardware to DRI clients
+ * The cursor animation timer has expired, go display any relevant cursor changes
+ * and compute a new timeout value
  */
 
-static void
-AnimCurScreenBlockHandler(ScreenPtr pScreen,
-                          void *pTimeout, void *pReadmask)
+static CARD32
+AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
 {
+    ScreenPtr pScreen = arg;
     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
     DeviceIntPtr dev;
     Bool activeDevice = FALSE;
-    CARD32 now = 0, soonest = ~0;       /* earliest time to wakeup again */
-
-    Unwrap(as, pScreen, BlockHandler);
+    CARD32 soonest = ~0;       /* earliest time to wakeup again */
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
-            if (!activeDevice) {
-                now = GetTimeInMillis();
+            if (!activeDevice)
                 activeDevice = TRUE;
-            }
 
             if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) {
                 AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor);
@@ -180,13 +174,11 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     }
 
     if (activeDevice)
-        AdjustWaitForDelay(pTimeout, soonest - now);
-
-    (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
-    if (activeDevice)
-        Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+        TimerSet(as->timer, TimerAbsolute, soonest, AnimCurTimerNotify, pScreen);
     else
-        as->BlockHandler = NULL;
+        as->timer_set = FALSE;
+
+    return 0;
 }
 
 static Bool
@@ -212,8 +204,11 @@ AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
                 pDev->spriteInfo->anim.pCursor = pCursor;
                 pDev->spriteInfo->anim.pScreen = pScreen;
 
-                if (!as->BlockHandler)
-                    Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+                if (!as->timer_set) {
+                    TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
+                             AnimCurTimerNotify, pScreen);
+                    as->timer_set = TRUE;
+                }
             }
         }
         else
@@ -239,8 +234,11 @@ AnimCurSetCursorPosition(DeviceIntPtr pDev,
     if (pDev->spriteInfo->anim.pCursor) {
         pDev->spriteInfo->anim.pScreen = pScreen;
 
-        if (!as->BlockHandler)
-            Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
+        if (!as->timer_set) {
+            TimerSet(as->timer, TimerAbsolute, pDev->spriteInfo->anim.time,
+                     AnimCurTimerNotify, pScreen);
+            as->timer_set = TRUE;
+        }
     }
     ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
     Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
@@ -316,9 +314,14 @@ AnimCurInit(ScreenPtr pScreen)
     as = (AnimCurScreenPtr) malloc(sizeof(AnimCurScreenRec));
     if (!as)
         return FALSE;
-    Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
+    as->timer = TimerSet(NULL, TimerAbsolute, 0, AnimCurTimerNotify, pScreen);
+    if (!as->timer) {
+        free(as);
+        return FALSE;
+    }
+    as->timer_set = FALSE;
 
-    as->BlockHandler = NULL;
+    Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
 
     Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
     Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
commit 49c0f2413d32fdfe36e45861fcb32aaeab633094
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:14 2015 -0800

    os/xdmcp: Replace xdmcp block/wakeup handlers with timer and NotifyFd
    
    This removes the block and wakeup handlers and replaces them with a
    combination of a NotifyFd callback and timers.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/xdmcp.c b/os/xdmcp.c
index 5bdcbe9..dbf43ef 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -82,10 +82,10 @@ static struct sockaddr_in req_sockaddr;
 #endif
 static int req_socklen;
 static CARD32 SessionID;
-static CARD32 timeOutTime;
 static int timeOutRtx;
 static CARD16 DisplayNumber;
 static xdmcp_states XDM_INIT_STATE = XDM_OFF;
+static OsTimerPtr xdmcp_timer;
 
 #ifdef HASXDMAUTH
 static char *xdmAuthCookie;
@@ -197,13 +197,9 @@ static void send_packet(void);
 
 static void timeout(void);
 
-static void XdmcpBlockHandler(void              *data ,
-                              struct timeval    **wt,
-                              void              *LastSelectMask);
+static void XdmcpSocketNotify(int fd, int ready, void *data);
 
-static void XdmcpWakeupHandler(void             *data,
-                               int              i,
-                               void             *LastSelectMask);
+static CARD32 XdmcpTimerNotify(OsTimerPtr timer, CARD32 time, void *arg);
 
 /*
  * Register the Manufacturer display ID
@@ -579,6 +575,21 @@ XdmcpRegisterDisplayClass(const char *name, int length)
         DisplayClass.data[i] = (CARD8) name[i];
 }
 
+static void
+xdmcp_start(void)
+{
+    timeOutRtx = 0;
+    get_xdmcp_sock();
+    if (xdmcpSocket >= 0)
+        SetNotifyFd(xdmcpSocket, XdmcpSocketNotify, X_NOTIFY_READ, NULL);
+#if defined(IPv6) && defined(AF_INET6)
+    if (xdmcpSocket6 >= 0)
+        SetNotifyFd(xdmcpSocket6, XdmcpSocketNotify, X_NOTIFY_READ, NULL);
+#endif
+    xdmcp_timer = TimerSet(NULL, 0, 0, XdmcpTimerNotify, NULL);
+    send_packet();
+}
+
 /*
  * initialize XDMCP; create the socket, compute the display
  * number, set up the state machine
@@ -597,12 +608,8 @@ XdmcpInit(void)
         XdmcpRegisterDisplayClass(defaultDisplayClass,
                                   strlen(defaultDisplayClass));
         AccessUsingXdmcp();
-        RegisterBlockAndWakeupHandlers(XdmcpBlockHandler, XdmcpWakeupHandler,
-                                       (void *) 0);
-        timeOutRtx = 0;
         DisplayNumber = (CARD16) atoi(display);
-        get_xdmcp_sock();
-        send_packet();
+        xdmcp_start();
     }
 }
 
@@ -610,12 +617,8 @@ void
 XdmcpReset(void)
 {
     state = XDM_INIT_STATE;
-    if (state != XDM_OFF) {
-        RegisterBlockAndWakeupHandlers(XdmcpBlockHandler, XdmcpWakeupHandler,
-                                       (void *) 0);
-        timeOutRtx = 0;
-        send_packet();
-    }
+    if (state != XDM_OFF)
+        xdmcp_start();
 }
 
 /*
@@ -630,7 +633,7 @@ XdmcpOpenDisplay(int sock)
     if (state != XDM_AWAIT_MANAGE_RESPONSE)
         return;
     state = XDM_RUN_SESSION;
-    timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000;
+    TimerSet(xdmcp_timer, 0, XDM_DEF_DORMANCY * 1000, XdmcpTimerNotify, NULL);
     sessionSocket = sock;
 }
 
@@ -648,69 +651,24 @@ XdmcpCloseDisplay(int sock)
     isItTimeToYield = TRUE;
 }
 
-/*
- * called before going to sleep, this routine
- * may modify the timeout value about to be sent
- * to select; in this way XDMCP can do appropriate things
- * dynamically while starting up
- */
-
- /*ARGSUSED*/ static void
-XdmcpBlockHandler(void *data, /* unused */
-                  struct timeval **wt, void *pReadmask)
+static void
+XdmcpSocketNotify(int fd, int ready, void *data)
 {
-    fd_set *last_select_mask = (fd_set *) pReadmask;
-    CARD32 millisToGo;
-
     if (state == XDM_OFF)
         return;
-    FD_SET(xdmcpSocket, last_select_mask);
-#if defined(IPv6) && defined(AF_INET6)
-    if (xdmcpSocket6 >= 0)
-        FD_SET(xdmcpSocket6, last_select_mask);
-#endif
-    if (timeOutTime == 0)
-        return;
-    millisToGo = timeOutTime - GetTimeInMillis();
-    if ((int) millisToGo < 0)
-        millisToGo = 0;
-    AdjustWaitForDelay(wt, millisToGo);
+    receive_packet(fd);
 }
 
-/*
- * called after select returns; this routine will
- * recognise when XDMCP packets await and
- * process them appropriately
- */
-
- /*ARGSUSED*/ static void
-XdmcpWakeupHandler(void *data,        /* unused */
-                   int i, void *pReadmask)
+static CARD32
+XdmcpTimerNotify(OsTimerPtr timer, CARD32 time, void *arg)
 {
-    fd_set *last_select_mask = (fd_set *) pReadmask;
-
-    if (state == XDM_OFF)
-        return;
-    if (i > 0) {
-        if (FD_ISSET(xdmcpSocket, last_select_mask)) {
-            receive_packet(xdmcpSocket);
-            FD_CLR(xdmcpSocket, last_select_mask);
-        }
-#if defined(IPv6) && defined(AF_INET6)
-        if (xdmcpSocket6 >= 0 && FD_ISSET(xdmcpSocket6, last_select_mask)) {
-            receive_packet(xdmcpSocket6);
-            FD_CLR(xdmcpSocket6, last_select_mask);
-        }
-#endif
-    }
-    else if (timeOutTime && (int) (GetTimeInMillis() - timeOutTime) >= 0) {
-        if (state == XDM_RUN_SESSION) {
-            state = XDM_KEEPALIVE;
-            send_packet();
-        }
-        else
-            timeout();
+    if (state == XDM_RUN_SESSION) {
+        state = XDM_KEEPALIVE;
+        send_packet();
     }
+    else
+        timeout();
+    return 0;
 }
 
 /*
@@ -832,7 +790,7 @@ send_packet(void)
     rtx = (XDM_MIN_RTX << timeOutRtx);
     if (rtx > XDM_MAX_RTX)
         rtx = XDM_MAX_RTX;
-    timeOutTime = GetTimeInMillis() + rtx * 1000;
+    TimerSet(xdmcp_timer, 0, rtx * 1000, XdmcpTimerNotify, NULL);
 }
 
 /*
@@ -847,7 +805,7 @@ XdmcpDeadSession(const char *reason)
     state = XDM_INIT_STATE;
     isItTimeToYield = TRUE;
     dispatchException |= DE_RESET;
-    timeOutTime = 0;
+    TimerCancel(xdmcp_timer);
     timeOutRtx = 0;
     send_packet();
 }
@@ -1391,7 +1349,7 @@ recv_alive_msg(unsigned length)
         XdmcpReadCARD32(&buffer, &AliveSessionID)) {
         if (SessionRunning && AliveSessionID == SessionID) {
             state = XDM_RUN_SESSION;
-            timeOutTime = GetTimeInMillis() + XDM_DEF_DORMANCY * 1000;
+            TimerSet(xdmcp_timer, 0, XDM_DEF_DORMANCY * 1000, XdmcpTimerNotify, NULL);
         }
         else {
             XdmcpDeadSession("Alive response indicates session dead");
commit 6a121f55381ecbb9cdaaef36ba6135890f3e006f
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:13 2015 -0800

    Xext/xselinux: Use NotifyFd interface
    
    Replace block/wakeup handlers with SetNotifyFd. Much nicer now.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xselinux_hooks.c b/Xext/xselinux_hooks.c
index d9f2f68..2d85928 100644
--- a/Xext/xselinux_hooks.c
+++ b/Xext/xselinux_hooks.c
@@ -810,15 +810,9 @@ SELinuxResourceState(CallbackListPtr *pcbl, void *unused, void *calldata)
 static int netlink_fd;
 
 static void
-SELinuxBlockHandler(void *data, struct timeval **tv, void *read_mask)
+SELinuxNetlinkNotify(int fd, int ready, void *data)
 {
-}
-
-static void
-SELinuxWakeupHandler(void *data, int num_fds, void *read_mask)
-{
-    if (num_fds > 0 && FD_ISSET(netlink_fd, (fd_set *) read_mask))
-        avc_netlink_check_nb();
+    avc_netlink_check_nb();
 }
 
 void
@@ -844,9 +838,7 @@ SELinuxFlaskReset(void)
     /* Tear down SELinux stuff */
     audit_close(audit_fd);
     avc_netlink_release_fd();
-    RemoveBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
-                                 NULL);
-    RemoveGeneralSocket(netlink_fd);
+    RemoveNotifyFd(netlink_fd);
 
     avc_destroy();
 }
@@ -918,9 +910,7 @@ SELinuxFlaskInit(void)
         FatalError("SELinux: Failed to create atom\n");
 
     netlink_fd = avc_netlink_acquire_fd();
-    AddGeneralSocket(netlink_fd);
-    RegisterBlockAndWakeupHandlers(SELinuxBlockHandler, SELinuxWakeupHandler,
-                                   NULL);
+    SetNotifyFd(netlink_fd, SELinuxNetlinkNotify, X_NOTIFY_READ, NULL);
 
     /* Register callbacks */
     ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL);
commit f933a1b38ed1c65cc39fce1ee37aa18e3022c3f0
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Nov 23 17:36:53 2015 -0800

    hw/xwayland: Use NotifyFd handler to monitor wayland socket
    
    Replace the block/wakeup handler with a NotifyFd callback instead.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 55bf6d0..3d36205 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -115,6 +115,8 @@ xwl_close_screen(ScreenPtr screen)
                                   &xwl_screen->seat_list, link)
         xwl_seat_destroy(xwl_seat);
 
+    RemoveNotifyFd(xwl_screen->wayland_fd);
+
     wl_display_disconnect(xwl_screen->display);
 
     screen->CloseScreen = xwl_screen->CloseScreen;
@@ -453,17 +455,11 @@ static const struct wl_registry_listener registry_listener = {
 };
 
 static void
-wakeup_handler(void *data, int err, void *read_mask)
+socket_handler(int fd, int ready, void *data)
 {
     struct xwl_screen *xwl_screen = data;
     int ret;
 
-    if (err < 0)
-        return;
-
-    if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask))
-        return;
-
     ret = wl_display_read_events(xwl_screen->display);
     if (ret == -1)
         FatalError("failed to dispatch Wayland events: %s\n", strerror(errno));
@@ -476,7 +472,12 @@ wakeup_handler(void *data, int err, void *read_mask)
 }
 
 static void
-block_handler(void *data, struct timeval **tv, void *read_mask)
+wakeup_handler(void *data, int err, void *pRead)
+{
+}
+
+static void
+block_handler(void *data, OSTimePtr pTimeout, void *pRead)
 {
     struct xwl_screen *xwl_screen = data;
     int ret;
@@ -651,7 +652,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
 #endif
 
     xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display);
-    AddGeneralSocket(xwl_screen->wayland_fd);
+    SetNotifyFd(xwl_screen->wayland_fd, socket_handler, X_NOTIFY_READ, xwl_screen);
     RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen);
 
     pScreen->SaveScreen = xwl_save_screen;
commit 8543d4d8bc0526d1c910913b76259e5dee108e74
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:11 2015 -0800

    modesetting: Use NotifyFd for drm event monitoring
    
    Replace the block/wakeup handlers with a NotifyFd callback.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 77e0848..869472a 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -244,18 +244,16 @@ ms_crtc_msc_to_kernel_msc(xf86CrtcPtr crtc, uint64_t expect)
  * Check for pending DRM events and process them.
  */
 static void
-ms_drm_wakeup_handler(void *data, int err, void *mask)
+ms_drm_socket_handler(int fd, int ready, void *data)
 {
     ScreenPtr screen = data;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     modesettingPtr ms = modesettingPTR(scrn);
-    fd_set *read_mask = mask;
 
-    if (data == NULL || err < 0)
+    if (data == NULL)
         return;
 
-    if (FD_ISSET(ms->fd, read_mask))
-        drmHandleEvent(ms->fd, &ms->event_context);
+    drmHandleEvent(ms->fd, &ms->event_context);
 }
 
 /*
@@ -393,9 +391,7 @@ ms_vblank_screen_init(ScreenPtr screen)
      * registration within ScreenInit and not PreInit.
      */
     if (ms_ent->fd_wakeup_registered != serverGeneration) {
-        AddGeneralSocket(ms->fd);
-        RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
-                                       ms_drm_wakeup_handler, screen);
+        SetNotifyFd(ms->fd, ms_drm_socket_handler, X_NOTIFY_READ, screen);
         ms_ent->fd_wakeup_registered = serverGeneration;
         ms_ent->fd_wakeup_ref = 1;
     } else
@@ -415,8 +411,6 @@ ms_vblank_close_screen(ScreenPtr screen)
 
     if (ms_ent->fd_wakeup_registered == serverGeneration &&
         !--ms_ent->fd_wakeup_ref) {
-        RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
-                                     ms_drm_wakeup_handler, screen);
-        RemoveGeneralSocket(ms->fd);
+        RemoveNotifyFd(ms->fd);
     }
 }
commit 58354fcf472cefc35b9c19cf84bf079cadfa2e1d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:10 2015 -0800

    kdrive/ephyr: Use NotifyFd for XCB connection input [v2]
    
    Eliminates polling every 20ms for device input.
    
    v2: rename ephyrPoll to ephyrXcbNotify and fix the API so it can be
        used directly for SetNotifyFd. Thanks to Daniel Martin
        <consume.noise at gmail.com>
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Cc: Daniel Martin <consume.noise at gmail.com>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index cb1c16e..896bac5 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1182,8 +1182,8 @@ ephyrProcessConfigureNotify(xcb_generic_event_t *xev)
 #endif /* RANDR */
 }
 
-void
-ephyrPoll(void)
+static void
+ephyrXcbNotify(int fd, int ready, void *data)
 {
     xcb_connection_t *conn = hostx_get_xcbconn();
 
@@ -1334,6 +1334,7 @@ static Status
 MouseEnable(KdPointerInfo * pi)
 {
     ((EphyrPointerPrivate *) pi->driverPrivate)->enabled = TRUE;
+    SetNotifyFd(hostx_get_fd(), ephyrXcbNotify, X_NOTIFY_READ, NULL);
     return Success;
 }
 
@@ -1341,6 +1342,7 @@ static void
 MouseDisable(KdPointerInfo * pi)
 {
     ((EphyrPointerPrivate *) pi->driverPrivate)->enabled = FALSE;
+    RemoveNotifyFd(hostx_get_fd());
     return;
 }
 
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 18bfe11..f5015f6 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -168,9 +168,6 @@ Bool
 Bool
  ephyrCreateColormap(ColormapPtr pmap);
 
-void
- ephyrPoll(void);
-
 #ifdef RANDR
 Bool
  ephyrRandRGetInfo(ScreenPtr pScreen, Rotation * rotations);
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 3991c51..49516bb 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -1113,6 +1113,12 @@ hostx_get_screen(void)
 }
 
 int
+hostx_get_fd(void)
+{
+    return xcb_get_file_descriptor(HostX.conn);
+}
+
+int
 hostx_get_window(int a_screen_number)
 {
     EphyrScrPriv *scrpriv;
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 9299e8d..d416dae 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -198,4 +198,6 @@ int hostx_has_dri(void);
 int hostx_has_glx(void);
 #endif                          /* XF86DRI */
 
+int hostx_get_fd(void);
+
 #endif /*_XLIBS_STUFF_H_*/
diff --git a/hw/kdrive/ephyr/os.c b/hw/kdrive/ephyr/os.c
index 0dbcbb8..b481d0a 100644
--- a/hw/kdrive/ephyr/os.c
+++ b/hw/kdrive/ephyr/os.c
@@ -45,5 +45,4 @@ EphyrInit(void)
 
 KdOsFuncs EphyrOsFuncs = {
     .Init = EphyrInit,
-    .pollEvents = ephyrPoll,
 };
commit 483c2a1adf044ba1da844687b908c1c802060d2d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:09 2015 -0800

    hw/kdrive: Use NotifyFd for kdrive input devices
    
    This switches the kdrive code to use FD notification for input
    devices, rather than the block and wakeup handlers.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 84b980f..1fdaa52 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -153,7 +153,16 @@ KdNonBlockFd(int fd)
 }
 
 static void
-KdAddFd(int fd)
+KdNotifyFd(int fd, int ready, void *data)
+{
+    int i = (int) (intptr_t) data;
+    OsBlockSIGIO();
+    (*kdInputFds[i].read)(fd, kdInputFds[i].closure);
+    OsReleaseSIGIO();
+}
+
+static void
+KdAddFd(int fd, int i)
 {
     struct sigaction act;
     sigset_t set;
@@ -162,6 +171,7 @@ KdAddFd(int fd)
     fcntl(fd, F_SETOWN, getpid());
     KdNonBlockFd(fd);
     AddEnabledDevice(fd);
+    SetNotifyFd(fd, KdNotifyFd, X_NOTIFY_READ, (void *) (intptr_t) i);
     memset(&act, '\0', sizeof act);
     act.sa_handler = KdSigio;
     sigemptyset(&act.sa_mask);
@@ -181,6 +191,7 @@ KdRemoveFd(int fd)
 
     kdnFds--;
     RemoveEnabledDevice(fd);
+    RemoveNotifyFd(fd);
     flags = fcntl(fd, F_GETFL);
     flags &= ~(FASYNC | NOBLOCK);
     fcntl(fd, F_SETFL, flags);
@@ -202,9 +213,9 @@ KdRegisterFd(int fd, void (*read) (int fd, void *closure), void *closure)
     kdInputFds[kdNumInputFds].enable = 0;
     kdInputFds[kdNumInputFds].disable = 0;
     kdInputFds[kdNumInputFds].closure = closure;
-    kdNumInputFds++;
     if (kdInputEnabled)
-        KdAddFd(fd);
+        KdAddFd(fd, kdNumInputFds);
+    kdNumInputFds++;
     return TRUE;
 }
 
@@ -1933,19 +1944,8 @@ KdBlockHandler(ScreenPtr pScreen, void *timeo, void *readmask)
 void
 KdWakeupHandler(ScreenPtr pScreen, unsigned long lresult, void *readmask)
 {
-    int result = (int) lresult;
-    fd_set *pReadmask = (fd_set *) readmask;
-    int i;
     KdPointerInfo *pi;
 
-    if (kdInputEnabled && result > 0) {
-        for (i = 0; i < kdNumInputFds; i++)
-            if (FD_ISSET(kdInputFds[i].fd, pReadmask)) {
-                OsBlockSIGIO();
-                (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
-                OsReleaseSIGIO();
-            }
-    }
     for (pi = kdPointers; pi; pi = pi->next) {
         if (pi->timeoutPending) {
             if ((long) (GetTimeInMillis() - pi->emulationTimeout) >= 0) {
commit 21c1680e83865a52d88cf8c80fb236d212931e5c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:08 2015 -0800

    hw/kdrive: Use NotifyFd interface for kdrive/linux APM monitoring
    
    Replace the block/wakeup handlers with a NotifyFd callback
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/kdrive/linux/linux.c b/hw/kdrive/linux/linux.c
index 73a8169..a52bdef 100644
--- a/hw/kdrive/linux/linux.c
+++ b/hw/kdrive/linux/linux.c
@@ -169,19 +169,12 @@ LinuxSetSwitchMode(int mode)
     }
 }
 
-static void
-LinuxApmBlock(void *blockData, OSTimePtr pTimeout, void *pReadmask)
-{
-}
-
 static Bool LinuxApmRunning;
 
 static void
-LinuxApmWakeup(void *blockData, int result, void *pReadmask)
+LinuxApmNotify(int fd, int mask, void *blockData)
 {
-    fd_set *readmask = (fd_set *) pReadmask;
-
-    if (result > 0 && LinuxApmFd >= 0 && FD_ISSET(LinuxApmFd, readmask)) {
+    if (LinuxApmFd >= 0) {
         apm_event_t event;
         Bool running = LinuxApmRunning;
         int cmd = APM_IOC_SUSPEND;
@@ -242,8 +235,7 @@ LinuxEnable(void)
     if (LinuxApmFd >= 0) {
         LinuxApmRunning = TRUE;
         fcntl(LinuxApmFd, F_SETFL, fcntl(LinuxApmFd, F_GETFL) | NOBLOCK);
-        RegisterBlockAndWakeupHandlers(LinuxApmBlock, LinuxApmWakeup, 0);
-        AddEnabledDevice(LinuxApmFd);
+        SetNotifyFd(LinuxApmFd, LinuxApmNotify, X_NOTIFY_READ, NULL);
     }
 
     /*
@@ -273,8 +265,7 @@ LinuxDisable(void)
     }
     enabled = FALSE;
     if (LinuxApmFd >= 0) {
-        RemoveBlockAndWakeupHandlers(LinuxApmBlock, LinuxApmWakeup, 0);
-        RemoveEnabledDevice(LinuxApmFd);
+        RemoveNotifyFd(LinuxApmFd);
         close(LinuxApmFd);
         LinuxApmFd = -1;
     }
commit 8c8f3567fe4b4e372e22420810443c43e008da2c
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:07 2015 -0800

    config: Use NotifyFd interface for udev
    
    This uses the NotifyFd interface to monitor the udev file descriptor
    rather than adding another block/wakeup handler
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/udev.c b/config/udev.c
index 28c2658..08a954b 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -332,41 +332,30 @@ device_removed(struct udev_device *device)
 }
 
 static void
-wakeup_handler(void *data, int err, void *read_mask)
+socket_handler(int fd, int ready, void *data)
 {
-    int udev_fd = udev_monitor_get_fd(udev_monitor);
     struct udev_device *udev_device;
     const char *action;
 
-    if (err < 0)
+    udev_device = udev_monitor_receive_device(udev_monitor);
+    if (!udev_device)
         return;
-
-    if (FD_ISSET(udev_fd, (fd_set *) read_mask)) {
-        udev_device = udev_monitor_receive_device(udev_monitor);
-        if (!udev_device)
-            return;
-        action = udev_device_get_action(udev_device);
-        if (action) {
-            if (!strcmp(action, "add")) {
+    action = udev_device_get_action(udev_device);
+    if (action) {
+        if (!strcmp(action, "add")) {
+            device_removed(udev_device);
+            device_added(udev_device);
+        } else if (!strcmp(action, "change")) {
+            /* ignore change for the drm devices */
+            if (strcmp(udev_device_get_subsystem(udev_device), "drm")) {
                 device_removed(udev_device);
                 device_added(udev_device);
-            } else if (!strcmp(action, "change")) {
-                /* ignore change for the drm devices */
-                if (strcmp(udev_device_get_subsystem(udev_device), "drm")) {
-                    device_removed(udev_device);
-                    device_added(udev_device);
-                }
             }
-            else if (!strcmp(action, "remove"))
-                device_removed(udev_device);
         }
-        udev_device_unref(udev_device);
+        else if (!strcmp(action, "remove"))
+            device_removed(udev_device);
     }
-}
-
-static void
-block_handler(void *data, struct timeval **tv, void *read_mask)
-{
+    udev_device_unref(udev_device);
 }
 
 int
@@ -441,8 +430,7 @@ config_udev_init(void)
     }
     udev_enumerate_unref(enumerate);
 
-    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
-    AddGeneralSocket(udev_monitor_get_fd(udev_monitor));
+    SetNotifyFd(udev_monitor_get_fd(udev_monitor), socket_handler, X_NOTIFY_READ, NULL);
 
     return 1;
 }
@@ -457,8 +445,7 @@ config_udev_fini(void)
 
     udev = udev_monitor_get_udev(udev_monitor);
 
-    RemoveGeneralSocket(udev_monitor_get_fd(udev_monitor));
-    RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, NULL);
+    RemoveNotifyFd(udev_monitor_get_fd(udev_monitor));
     udev_monitor_unref(udev_monitor);
     udev_monitor = NULL;
     udev_unref(udev);
commit bf920b2390dc27947f87dd0b228518290a5ed85d
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:06 2015 -0800

    config: Use NotifyFd for dbus interface
    
    This uses the NotifyFd interface to monitor the dbus socket rather
    than a block/wakeup handler.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/dbus-core.c b/config/dbus-core.c
index 8351ea4..3c85ad7 100644
--- a/config/dbus-core.c
+++ b/config/dbus-core.c
@@ -48,11 +48,11 @@ static struct dbus_core_info bus_info;
 static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, void *arg);
 
 static void
-wakeup_handler(void *data, int num_fds, void *read_mask)
+socket_handler(int fd, int ready, void *data)
 {
     struct dbus_core_info *info = data;
 
-    if (info->connection && num_fds > 0 && FD_ISSET(info->fd, (fd_set *) read_mask)) {
+    if (info->connection) {
         do {
             dbus_connection_read_write_dispatch(info->connection, 0);
         } while (info->connection &&
@@ -62,11 +62,6 @@ wakeup_handler(void *data, int num_fds, void *read_mask)
     }
 }
 
-static void
-block_handler(void *data, struct timeval **tv, void *read_mask)
-{
-}
-
 /**
  * Disconnect (if we haven't already been forcefully disconnected), clean up
  * after ourselves, and call all registered disconnect hooks.
@@ -87,9 +82,8 @@ teardown(void)
     if (bus_info.connection)
         dbus_connection_unref(bus_info.connection);
 
-    RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
     if (bus_info.fd != -1)
-        RemoveGeneralSocket(bus_info.fd);
+        RemoveNotifyFd(bus_info.fd);
     bus_info.fd = -1;
     bus_info.connection = NULL;
 
@@ -162,9 +156,7 @@ connect_to_bus(void)
     }
 
     dbus_error_free(&error);
-    AddGeneralSocket(bus_info.fd);
-
-    RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
+    SetNotifyFd(bus_info.fd, socket_handler, X_NOTIFY_READ, &bus_info);
 
     for (hook = bus_info.hooks; hook; hook = hook->next) {
         if (hook->connect)
commit 91ea0965dd4dfeba0a914c47ad4a64768e983b1b
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:04 2015 -0800

    dix: Move InitFonts up above screen initialization
    
    Font initialization was split into two stages, the first was to set up
    font privates with a call to ResetFontPrivateIndex, then much later
    the call to InitFonts to set up all of the FPEs. Doing the full font
    initialization before initializing the video drivers means that we can
    move the call to ResetFontPrivateIndex inside InitFonts.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index 300bf04..19db141 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -1809,6 +1809,8 @@ InitFonts(void)
 {
     patternCache = MakeFontPatternCache();
 
+    ResetFontPrivateIndex();
+
     register_fpe_functions();
 }
 
diff --git a/dix/main.c b/dix/main.c
index 5495676..661ab03 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -199,7 +199,7 @@ dix_main(int argc, char *argv[], char *envp[])
         InitEvents();
         InitGlyphCaching();
         dixResetRegistry();
-        ResetFontPrivateIndex();
+        InitFonts();
         InitCallbackManager();
         InitOutput(&screenInfo, argc, argv);
 
@@ -232,7 +232,6 @@ dix_main(int argc, char *argv[], char *envp[])
                 FatalError("failed to create root window");
         }
 
-        InitFonts();
         if (SetDefaultFontPath(defaultFontPath) != Success) {
             ErrorF("[dix] failed to set default font path '%s'",
                    defaultFontPath);
commit 4020aacd1fc5b9c63369f011aeb9120af9c55218
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:03 2015 -0800

    os: Implement support for NotifyFd X_NOTIFY_WRITE
    
    This adds the ability to be notified when a file descriptor is
    available for writing.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/WaitFor.c b/os/WaitFor.c
index 12b21bb..b579e1b 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -156,6 +156,7 @@ WaitForSomething(int *pClientsReady)
     fd_set devicesReadable;
     CARD32 now = 0;
     Bool someReady = FALSE;
+    Bool someNotifyWriteReady = FALSE;
 
     FD_ZERO(&clientsReadable);
     FD_ZERO(&clientsWritable);
@@ -213,9 +214,10 @@ WaitForSomething(int *pClientsReady)
         /* keep this check close to select() call to minimize race */
         if (dispatchException)
             i = -1;
-        else if (AnyClientsWriteBlocked) {
-            XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable);
-            i = Select(MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
+        else if (AnyWritesPending) {
+            XFD_COPYSET(&ClientsWriteBlocked, &LastSelectWriteMask);
+            XFD_ORSET(&LastSelectWriteMask, &NotifyWriteFds, &LastSelectWriteMask);
+            i = Select(MaxClients, &LastSelectMask, &LastSelectWriteMask, NULL, wt);
         }
         else {
             i = Select(MaxClients, &LastSelectMask, NULL, NULL, wt);
@@ -291,12 +293,20 @@ WaitForSomething(int *pClientsReady)
             }
             if (someReady)
                 XFD_ORSET(&LastSelectMask, &ClientsWithInput, &LastSelectMask);
-            if (AnyClientsWriteBlocked && XFD_ANYSET(&clientsWritable)) {
-                NewOutputPending = TRUE;
-                XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
-                XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
-                if (!XFD_ANYSET(&ClientsWriteBlocked))
-                    AnyClientsWriteBlocked = FALSE;
+            if (AnyWritesPending) {
+                XFD_ANDSET(&clientsWritable, &LastSelectWriteMask, &ClientsWriteBlocked);
+                if (XFD_ANYSET(&clientsWritable)) {
+                    NewOutputPending = TRUE;
+                    XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
+                    XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
+                    if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+                        AnyWritesPending = FALSE;
+                }
+                if (NumNotifyWriteFd != 0) {
+                    XFD_ANDSET(&tmp_set, &LastSelectWriteMask, &NotifyWriteFds);
+                    if (XFD_ANYSET(&tmp_set))
+                        someNotifyWriteReady = TRUE;
+                }
             }
 
             XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices);
@@ -307,7 +317,7 @@ WaitForSomething(int *pClientsReady)
                               (void *) &LastSelectMask);
 
             XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
-            if (XFD_ANYSET(&tmp_set))
+            if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
                 HandleNotifyFds();
 
             if (XFD_ANYSET(&devicesReadable) || XFD_ANYSET(&clientsReadable))
diff --git a/os/connection.c b/os/connection.c
index 0df4391..4da01a6 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -124,15 +124,18 @@ static int lastfdesc;           /* maximum file descriptor */
 fd_set WellKnownConnections;    /* Listener mask */
 fd_set EnabledDevices;          /* mask for input devices that are on */
 fd_set NotifyReadFds;           /* mask for other file descriptors */
+fd_set NotifyWriteFds;          /* mask for other write file descriptors */
 fd_set AllSockets;              /* select on this */
 fd_set AllClients;              /* available clients */
 fd_set LastSelectMask;          /* mask returned from last select call */
+fd_set LastSelectWriteMask;     /* mask returned from last select call */
 fd_set ClientsWithInput;        /* clients with FULL requests in buffer */
 fd_set ClientsWriteBlocked;     /* clients who cannot receive output */
 fd_set OutputPending;           /* clients with reply/event data ready to go */
 int MaxClients = 0;
+int NumNotifyWriteFd;           /* Number of NotifyFd members with write set */
 Bool NewOutputPending;          /* not yet attempted to write some new output */
-Bool AnyClientsWriteBlocked;    /* true if some client blocked on write */
+Bool AnyWritesPending;          /* true if some client blocked on write or NotifyFd with write */
 Bool NoListenAll;               /* Don't establish any listening sockets */
 
 static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
@@ -969,8 +972,8 @@ CloseDownFileDescriptor(OsCommPtr oc)
         FD_CLR(connection, &SavedClientsWithInput);
     }
     FD_CLR(connection, &ClientsWriteBlocked);
-    if (!XFD_ANYSET(&ClientsWriteBlocked))
-        AnyClientsWriteBlocked = FALSE;
+    if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+        AnyWritesPending = FALSE;
     FD_CLR(connection, &OutputPending);
 }
 
@@ -1112,6 +1115,7 @@ InitNotifyFds(void)
             RemoveNotifyFd(s->fd);
 
     xorg_list_init(&notify_fds);
+    NumNotifyWriteFd = 0;
     been_here = 1;
 }
 
@@ -1153,6 +1157,20 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
             FD_CLR(fd, &NotifyReadFds);
         }
     }
+
+    if (changes & X_NOTIFY_WRITE) {
+        if (mask & X_NOTIFY_WRITE) {
+            FD_SET(fd, &NotifyWriteFds);
+            if (!NumNotifyWriteFd++)
+                AnyWritesPending = TRUE;
+        } else {
+            FD_CLR(fd, &NotifyWriteFds);
+            if (!--NumNotifyWriteFd)
+                if (!XFD_ANYSET(&ClientsWriteBlocked))
+                    AnyWritesPending = FALSE;
+        }
+    }
+
     if (mask == 0) {
         xorg_list_del(&n->list);
         free(n);
@@ -1174,12 +1192,16 @@ SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
 void
 HandleNotifyFds(void)
 {
-    struct notify_fd *s, *next;
-
-    xorg_list_for_each_entry_safe(s, next, &notify_fds, list) {
-        if (FD_ISSET(s->fd, &LastSelectMask)) {
-            s->notify(s->fd, X_NOTIFY_READ, s->data);
-        }
+    struct notify_fd *n, *next;
+
+    xorg_list_for_each_entry_safe(n, next, &notify_fds, list) {
+        int ready = 0;
+        if ((n->mask & X_NOTIFY_READ) && FD_ISSET(n->fd, &LastSelectMask))
+            ready |= X_NOTIFY_READ;
+        if ((n->mask & X_NOTIFY_WRITE) & FD_ISSET(n->fd, &LastSelectWriteMask))
+            ready |= X_NOTIFY_WRITE;
+        if (ready != 0)
+            n->notify(n->fd, ready, n->data);
     }
 }
 
diff --git a/os/io.c b/os/io.c
index 971fdc9..19a449a 100644
--- a/os/io.c
+++ b/os/io.c
@@ -946,7 +946,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
                and not ready to accept more.  Make a note of it and buffer
                the rest. */
             FD_SET(connection, &ClientsWriteBlocked);
-            AnyClientsWriteBlocked = TRUE;
+            AnyWritesPending = TRUE;
 
             if (written < oco->count) {
                 if (written > 0) {
@@ -1009,10 +1009,10 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
     /* everything was flushed out */
     oco->count = 0;
     /* check to see if this client was write blocked */
-    if (AnyClientsWriteBlocked) {
+    if (AnyWritesPending) {
         FD_CLR(oc->fd, &ClientsWriteBlocked);
-        if (!XFD_ANYSET(&ClientsWriteBlocked))
-            AnyClientsWriteBlocked = FALSE;
+        if (!XFD_ANYSET(&ClientsWriteBlocked) && NumNotifyWriteFd == 0)
+            AnyWritesPending = FALSE;
     }
     if (oco->size > BUFWATERMARK) {
         free(oco->buf);
diff --git a/os/osdep.h b/os/osdep.h
index 2bfc783..2fbfc48 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -168,9 +168,11 @@ extern void HandleNotifyFds(void);
 extern fd_set AllSockets;
 extern fd_set AllClients;
 extern fd_set LastSelectMask;
+extern fd_set LastSelectWriteMask;
 extern fd_set WellKnownConnections;
 extern fd_set EnabledDevices;
 extern fd_set NotifyReadFds;
+extern fd_set NotifyWriteFds;
 extern fd_set ClientsWithInput;
 extern fd_set ClientsWriteBlocked;
 extern fd_set OutputPending;
@@ -185,7 +187,8 @@ extern void ClearConnectionTranslation(void);
 #endif
 
 extern Bool NewOutputPending;
-extern Bool AnyClientsWriteBlocked;
+extern Bool AnyWritesPending;
+extern Bool NumNotifyWriteFd;
 
 extern WorkQueuePtr workQueue;
 
commit 0c41b7af4ab0c8d22b88f201293f59524d1e7317
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:02 2015 -0800

    os: Add NotifyFd interfaces
    
    This provides a callback-based interface to monitor file
    descriptors beyond the usual client and device interfaces.
    
    Modules within the server using file descriptors for reading and/or
    writing can call
    
        Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data);
    
    mask can be any combination of X_NOTIFY_READ and X_NOTIFY_WRITE.
    
    When 'fd' becomes readable or writable, the notify_fd function will be
    called with the 'fd', the ready conditions and 'data' values as arguments,
    
    When the module no longer needs to monitor the fd, it will call
    
        void RemoveNotifyFd(int fd);
    
    RemoveNotifyFd may be called from the notify function.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/os.h b/include/os.h
index 9937f2e..aed2e2f 100644
--- a/include/os.h
+++ b/include/os.h
@@ -154,6 +154,19 @@ extern _X_EXPORT void AddEnabledDevice(int /*fd */ );
 
 extern _X_EXPORT void RemoveEnabledDevice(int /*fd */ );
 
+typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data);
+
+#define X_NOTIFY_NONE   0
+#define X_NOTIFY_READ   1
+#define X_NOTIFY_WRITE  2
+
+extern _X_EXPORT Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data);
+
+static inline void RemoveNotifyFd(int fd)
+{
+    (void) SetNotifyFd(fd, NULL, X_NOTIFY_NONE, NULL);
+}
+
 extern _X_EXPORT int OnlyListenToOneClient(ClientPtr /*client */ );
 
 extern _X_EXPORT void ListenToAllClients(void);
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 7325430..12b21bb 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -306,6 +306,10 @@ WaitForSomething(int *pClientsReady)
                 QueueWorkProc(EstablishNewConnections, NULL,
                               (void *) &LastSelectMask);
 
+            XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
+            if (XFD_ANYSET(&tmp_set))
+                HandleNotifyFds();
+
             if (XFD_ANYSET(&devicesReadable) || XFD_ANYSET(&clientsReadable))
                 break;
             /* check here for DDXes that queue events during Block/Wakeup */
diff --git a/os/connection.c b/os/connection.c
index 3d33c41..0df4391 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -123,6 +123,7 @@ static int lastfdesc;           /* maximum file descriptor */
 
 fd_set WellKnownConnections;    /* Listener mask */
 fd_set EnabledDevices;          /* mask for input devices that are on */
+fd_set NotifyReadFds;           /* mask for other file descriptors */
 fd_set AllSockets;              /* select on this */
 fd_set AllClients;              /* available clients */
 fd_set LastSelectMask;          /* mask returned from last select call */
@@ -1090,6 +1091,98 @@ RemoveEnabledDevice(int fd)
     RemoveGeneralSocket(fd);
 }
 
+struct notify_fd {
+    struct xorg_list list;
+    int fd;
+    int mask;
+    NotifyFdProcPtr notify;
+    void *data;
+};
+
+static struct xorg_list notify_fds;
+
+void
+InitNotifyFds(void)
+{
+    struct notify_fd *s, *next;
+    static int been_here;
+
+    if (been_here)
+        xorg_list_for_each_entry_safe(s, next, &notify_fds, list)
+            RemoveNotifyFd(s->fd);
+
+    xorg_list_init(&notify_fds);
+    been_here = 1;
+}
+
+/*****************
+ * SetNotifyFd
+ *    Registers a callback to be invoked when the specified
+ *    file descriptor becomes readable.
+ *****************/
+
+Bool
+SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
+{
+    struct notify_fd *n;
+    int changes;
+
+    xorg_list_for_each_entry(n, &notify_fds, list)
+        if (n->fd == fd)
+            break;
+
+    if (&n->list == &notify_fds) {
+        if (mask == 0)
+            return TRUE;
+
+        n = calloc(1, sizeof (struct notify_fd));
+        if (!n)
+            return FALSE;
+        n->fd = fd;
+        xorg_list_add(&n->list, &notify_fds);
+    }
+
+    changes = n->mask ^ mask;
+
+    if (changes & X_NOTIFY_READ) {
+        if (mask & X_NOTIFY_READ) {
+            FD_SET(fd, &NotifyReadFds);
+            AddGeneralSocket(fd);
+        } else {
+            RemoveGeneralSocket(fd);
+            FD_CLR(fd, &NotifyReadFds);
+        }
+    }
+    if (mask == 0) {
+        xorg_list_del(&n->list);
+        free(n);
+    } else {
+        n->mask = mask;
+        n->data = data;
+        n->notify = notify;
+    }
+
+    return TRUE;
+}
+
+/*****************
+ * HandlNotifyFds
+ *    A WorkProc to be called when any of the registered
+ *    file descriptors are readable.
+ *****************/
+
+void
+HandleNotifyFds(void)
+{
+    struct notify_fd *s, *next;
+
+    xorg_list_for_each_entry_safe(s, next, &notify_fds, list) {
+        if (FD_ISSET(s->fd, &LastSelectMask)) {
+            s->notify(s->fd, X_NOTIFY_READ, s->data);
+        }
+    }
+}
+
 /*****************
  * OnlyListenToOneClient:
  *    Only accept requests from  one client.  Continue to handle new
diff --git a/os/osdep.h b/os/osdep.h
index 86263a5..2bfc783 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -159,6 +159,10 @@ extern int FlushClient(ClientPtr /*who */ ,
 extern void FreeOsBuffers(OsCommPtr     /*oc */
     );
 
+extern void InitNotifyFds(void);
+
+extern void HandleNotifyFds(void);
+
 #include "dix.h"
 
 extern fd_set AllSockets;
@@ -166,6 +170,7 @@ extern fd_set AllClients;
 extern fd_set LastSelectMask;
 extern fd_set WellKnownConnections;
 extern fd_set EnabledDevices;
+extern fd_set NotifyReadFds;
 extern fd_set ClientsWithInput;
 extern fd_set ClientsWriteBlocked;
 extern fd_set OutputPending;
diff --git a/os/osinit.c b/os/osinit.c
index 6ec2f11..54b39a0 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -314,6 +314,7 @@ OsInit(void)
         LockServer();
         been_here = TRUE;
     }
+    InitNotifyFds();
     TimerInit();
     OsVendorInit();
     OsResetSignals();
commit e10ba9e4b52269b2ac75c4802dce4ca47d169657
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Nov 11 22:02:01 2015 -0800

    Remove non-smart scheduler. Don't require setitimer.
    
    This allows the server to call GetTimeInMillis() after each request is
    processed to avoid needing setitimer. -dumbSched now turns off the
    setitimer.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/configure.ac b/configure.ac
index 14a5bb8..2e38efa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -218,7 +218,7 @@ AC_SUBST(DLOPEN_LIBS)
 dnl Checks for library functions.
 AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \
 	getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \
-	mmap seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext])
+	mmap seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext setitimer])
 AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup])
 
 AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]])
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 2c20124..53032dc 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -222,11 +222,11 @@ UpdateCurrentTimeIf(void)
 #define SMART_SCHEDULE_DEFAULT_INTERVAL	5
 #define SMART_SCHEDULE_MAX_SLICE	15
 
-#if defined(WIN32) && !defined(__CYGWIN__)
-Bool SmartScheduleDisable = TRUE;
-#else
-Bool SmartScheduleDisable = FALSE;
+#ifdef HAVE_SETITIMER
+#define SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE HAVE_SETITIMER
+Bool SmartScheduleSignalEnable = SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE;
 #endif
+
 long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
 long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
 long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
@@ -358,7 +358,7 @@ Dispatch(void)
 
         nready = WaitForSomething(clientReady);
 
-        if (nready && !SmartScheduleDisable) {
+        if (nready) {
             clientReady[0] = SmartScheduleClient(clientReady, nready);
             nready = 1;
         }
@@ -386,8 +386,8 @@ Dispatch(void)
                     ProcessInputEvents();
 
                 FlushIfCriticalOutputPending();
-                if (!SmartScheduleDisable &&
-                    (SmartScheduleTime - start_tick) >= SmartScheduleSlice) {
+                if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+                {
                     /* Penalize clients which consume ticks */
                     if (client->smart_priority > SMART_MIN_PRIORITY)
                         client->smart_priority--;
@@ -431,6 +431,9 @@ Dispatch(void)
                             (*client->requestVector[client->majorOp]) (client);
                     XaceHookAuditEnd(client, result);
                 }
+                if (!SmartScheduleSignalEnable)
+                    SmartScheduleTime = GetTimeInMillis();
+
 #ifdef XSERVER_DTRACE
                 if (XSERVER_REQUEST_DONE_ENABLED())
                     XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 112ab95..940d2b7 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -518,4 +518,7 @@
 /* Define if no local socket credentials interface exists */
 #undef NO_LOCAL_CLIENT_CRED
 
+/* Have setitimer support */
+#undef HAVE_SETITIMER
+
 #endif /* _DIX_CONFIG_H_ */
diff --git a/include/dixstruct.h b/include/dixstruct.h
index 7575066..8e70ae1 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -130,7 +130,11 @@ extern long SmartScheduleTime;
 extern long SmartScheduleInterval;
 extern long SmartScheduleSlice;
 extern long SmartScheduleMaxSlice;
-extern Bool SmartScheduleDisable;
+#if HAVE_SETITIMER
+extern Bool SmartScheduleSignalEnable;
+#else
+#define SmartScheduleSignalEnable FALSE
+#endif
 extern void SmartScheduleStartTimer(void);
 extern void SmartScheduleStopTimer(void);
 
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 993c14e..7325430 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -175,16 +175,10 @@ WaitForSomething(int *pClientsReady)
         if (workQueue)
             ProcessWorkQueue();
         if (XFD_ANYSET(&ClientsWithInput)) {
-            if (!SmartScheduleDisable) {
-                someReady = TRUE;
-                waittime.tv_sec = 0;
-                waittime.tv_usec = 0;
-                wt = &waittime;
-            }
-            else {
-                XFD_COPYSET(&ClientsWithInput, &clientsReadable);
-                break;
-            }
+            someReady = TRUE;
+            waittime.tv_sec = 0;
+            waittime.tv_usec = 0;
+            wt = &waittime;
         }
         if (someReady) {
             XFD_COPYSET(&AllSockets, &LastSelectMask);
diff --git a/os/io.c b/os/io.c
index 55644ea..971fdc9 100644
--- a/os/io.c
+++ b/os/io.c
@@ -462,23 +462,14 @@ ReadRequestFromClient(ClientPtr client)
             )
             FD_SET(fd, &ClientsWithInput);
         else {
-            if (!SmartScheduleDisable)
-                FD_CLR(fd, &ClientsWithInput);
-            else
-                YieldControlNoInput(fd);
+            FD_CLR(fd, &ClientsWithInput);
         }
     }
     else {
         if (!gotnow)
             AvailableInput = oc;
-        if (!SmartScheduleDisable)
-            FD_CLR(fd, &ClientsWithInput);
-        else
-            YieldControlNoInput(fd);
+        FD_CLR(fd, &ClientsWithInput);
     }
-    if (SmartScheduleDisable)
-        if (++timesThisConnection >= MAX_TIMES_PER)
-            YieldControl();
     if (move_header) {
         request = (xReq *) oci->bufptr;
         oci->bufptr += (sizeof(xBigReq) - sizeof(xReq));
diff --git a/os/utils.c b/os/utils.c
index b45719e..ef7a2cc 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -71,7 +71,6 @@ __stdcall unsigned long GetTickCount(void);
 #if !defined(WIN32) || !defined(__MINGW32__)
 #include <sys/time.h>
 #include <sys/resource.h>
-# define SMART_SCHEDULE_POSSIBLE
 #endif
 #include "misc.h"
 #include <X11/X.h>
@@ -1005,10 +1004,11 @@ ProcessCommandLine(int argc, char *argv[])
             i = skip - 1;
         }
 #endif
-#ifdef SMART_SCHEDULE_POSSIBLE
+#if HAVE_SETITIMER
         else if (strcmp(argv[i], "-dumbSched") == 0) {
-            SmartScheduleDisable = TRUE;
+            SmartScheduleSignalEnable = FALSE;
         }
+#endif
         else if (strcmp(argv[i], "-schedInterval") == 0) {
             if (++i < argc) {
                 SmartScheduleInterval = atoi(argv[i]);
@@ -1024,7 +1024,6 @@ ProcessCommandLine(int argc, char *argv[])
             else
                 UseMsg();
         }
-#endif
         else if (strcmp(argv[i], "-render") == 0) {
             if (++i < argc) {
                 int policy = PictureParseCmapPolicy(argv[i]);
@@ -1208,10 +1207,10 @@ XNFstrdup(const char *s)
 void
 SmartScheduleStopTimer(void)
 {
-#ifdef SMART_SCHEDULE_POSSIBLE
+#if HAVE_SETITIMER
     struct itimerval timer;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return;
     timer.it_interval.tv_sec = 0;
     timer.it_interval.tv_usec = 0;
@@ -1224,10 +1223,10 @@ SmartScheduleStopTimer(void)
 void
 SmartScheduleStartTimer(void)
 {
-#ifdef SMART_SCHEDULE_POSSIBLE
+#if HAVE_SETITIMER
     struct itimerval timer;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return;
     timer.it_interval.tv_sec = 0;
     timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
@@ -1237,6 +1236,7 @@ SmartScheduleStartTimer(void)
 #endif
 }
 
+#if HAVE_SETITIMER
 static void
 SmartScheduleTimer(int sig)
 {
@@ -1247,10 +1247,9 @@ static int
 SmartScheduleEnable(void)
 {
     int ret = 0;
-#ifdef SMART_SCHEDULE_POSSIBLE
     struct sigaction act;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return 0;
 
     memset((char *) &act, 0, sizeof(struct sigaction));
@@ -1261,7 +1260,6 @@ SmartScheduleEnable(void)
     sigemptyset(&act.sa_mask);
     sigaddset(&act.sa_mask, SIGALRM);
     ret = sigaction(SIGALRM, &act, 0);
-#endif
     return ret;
 }
 
@@ -1269,10 +1267,9 @@ static int
 SmartSchedulePause(void)
 {
     int ret = 0;
-#ifdef SMART_SCHEDULE_POSSIBLE
     struct sigaction act;
 
-    if (SmartScheduleDisable)
+    if (!SmartScheduleSignalEnable)
         return 0;
 
     memset((char *) &act, 0, sizeof(struct sigaction));
@@ -1280,20 +1277,19 @@ SmartSchedulePause(void)
     act.sa_handler = SIG_IGN;
     sigemptyset(&act.sa_mask);
     ret = sigaction(SIGALRM, &act, 0);
-#endif
     return ret;
 }
+#endif
 
 void
 SmartScheduleInit(void)
 {
-    if (SmartScheduleDisable)
-        return;
-
+#if HAVE_SETITIMER
     if (SmartScheduleEnable() < 0) {
         perror("sigaction for smart scheduler");
-        SmartScheduleDisable = TRUE;
+        SmartScheduleSignalEnable = FALSE;
     }
+#endif
 }
 
 #ifdef SIG_BLOCK
@@ -1490,6 +1486,7 @@ Popen(const char *command, const char *type)
     }
 
     /* Ignore the smart scheduler while this is going on */
+#if HAVE_SETITIMER
     if (SmartSchedulePause() < 0) {
         close(pdes[0]);
         close(pdes[1]);
@@ -1497,14 +1494,17 @@ Popen(const char *command, const char *type)
         perror("signal");
         return NULL;
     }
+#endif
 
     switch (pid = fork()) {
     case -1:                   /* error */
         close(pdes[0]);
         close(pdes[1]);
         free(cur);
+#if HAVE_SETITIMER
         if (SmartScheduleEnable() < 0)
             perror("signal");
+#endif
         return NULL;
     case 0:                    /* child */
         if (setgid(getgid()) == -1)
@@ -1678,10 +1678,12 @@ Pclose(void *iop)
     /* allow EINTR again */
     OsReleaseSignals();
 
+#if HAVE_SETITIMER
     if (SmartScheduleEnable() < 0) {
         perror("signal");
         return -1;
     }
+#endif
 
     return pid == -1 ? -1 : pstat;
 }


More information about the xorg-commit mailing list