[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'upstream-experimental'



Rebased ref, commits from common ancestor:
commit 8db4121a3c7104548fd4a138ac1d1bdea5fd22d9
Author: Keith Packard <keithp@keithp.com>
Date:   Fri Oct 18 17:31:01 2013 -0700

    Update to version 1.14.99.3
    
    Signed-off-by: Keith Packard <keithp@keithp.com>

diff --git a/configure.ac b/configure.ac
index 67ef3c2..7b4e70f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,9 +26,9 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.14.99.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-10-04"
-RELEASE_NAME="Chicory Coffee"
+AC_INIT([xorg-server], 1.14.99.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-10-18"
+RELEASE_NAME="Bundaberg"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])
 

commit 2523a445a09a75a8baf642608d099a5e12d5437f
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Oct 17 12:02:27 2013 +1000

    sync: split updating and triggering a counter up
    
    Now that the brackets are always the nearest change points (regardless of
    transition) we need to update the counters whenever we check for any updates.
    
    Otherwise we end up with a situation where counter->value is out of date and
    an alarm doesn't trigger because we're still using the value from last time
    something actually triggered.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Keith Packard <keithp@keithp.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index ad3dec2..b2ee92e 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -699,6 +699,14 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger)
     FreeResource(pAwaitUnion->header.delete_id, RT_NONE);
 }
 
+static CARD64
+SyncUpdateCounter(SyncCounter *pCounter, CARD64 newval)
+{
+    CARD64 oldval = pCounter->value;
+    pCounter->value = newval;
+    return oldval;
+}
+
 /*  This function should always be used to change a counter's value so that
  *  any triggers depending on the counter will be checked.
  */
@@ -708,8 +716,7 @@ SyncChangeCounter(SyncCounter * pCounter, CARD64 newval)
     SyncTriggerList *ptl, *pnext;
     CARD64 oldval;
 
-    oldval = pCounter->value;
-    pCounter->value = newval;
+    oldval = SyncUpdateCounter(pCounter, newval);
 
     /* run through triggers to see if any become true */
     for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
@@ -2712,6 +2719,8 @@ IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, X
         (less && XSyncValueLessOrEqual(idle, *less))) {
         SyncChangeCounter(counter, idle);
     }
+    else
+        SyncUpdateCounter(counter, idle);
 }
 
 static void

commit e57ec99b03b2ad840c384a97ab2766ce9da0f5cc
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Oct 16 16:31:15 2013 +1000

    sync: always set the brackets (#59644)
    
    The current code sets bracket_greater to the first trigger after the current
    value, and bracket_less to the last trigger before the current value.
    
    For example, the idle timer with three negative and three positive transitions
    would set this:
    
             nt1       nt2                 nt3
    |--------|------|--|------- idle --|---|--|-----> t
                   pt1                pt2    pt3
    bracket_less == nt2
    bracket_greater == pt2
    
    This is an optimization so we can skip code paths in the block/wakeup handlers
    if the current value doesn't meet any of the trigger requirements. Those
    handlers largely do a
       if (bracket_less is less than current value &&
           bracket_greater is greater than current value)
            return, nothing to do
    
    However, unless the bracket values are updated at the correct time, the
    following may happen:
    
                                          nt
    |--------------|---------- idle ------|--------> t
                   pt
    
    In this case, neither bracket is set, we're past the pos transition and not
    yet at the neg transition. idle may now go past nt, but the brackets are not
    updated. If idle is then reset to 0, no alarm is triggered for nt. Likewise,
    idle may now go past pt and no alarm is triggered.
    
    Changing an alarm or triggering an alarm will re-calculate the brackets, so
    this bug is somewhat random. If any other client triggers an alarm when the
    brackets are wrongly NULL, the recalculation will set them this bug may not
    appear.
    
    This patch changes the behavior, so that the brackets are always the nearest
    positive or negative transitions to the current counter value. In the example
    above, nt will trigger a wakeup and a re-calculation of the brackets, so that
    going past it in the negative direction will then cause the proper alarm
    triggers.
    
    Or, in Keith's words:
    
      Timer currently past a positive trigger
          No bracket values, because no trigger in range
    
      Timer moves backwards before the positive trigger
          Brackets not reset, even though there is now a trigger in range
    
      Timer moves forward past the positive trigger
          Trigger doesn't fire because brackets not set
    
    Setting the LT bracket in this case will cause everything to get
    re-evaluated when the sync value moves backwards before the trigger
    value.
    
    X.Org Bug 59644 <http://bugs.freedesktop.org/show_bug.cgi?id=59644>
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Keith Packard <keithp@keithp.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index ab46d89..ad3dec2 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -1019,6 +1019,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                 psci->bracket_greater = pTrigger->test_value;
                 pnewgtval = &psci->bracket_greater;
             }
+            else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+                    psci->bracket_less = pTrigger->test_value;
+                    pnewltval = &psci->bracket_less;
+            }
         }
         else if (pTrigger->test_type == XSyncNegativeComparison &&
                  ct != XSyncCounterNeverDecreases) {
@@ -1028,6 +1033,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                 psci->bracket_less = pTrigger->test_value;
                 pnewltval = &psci->bracket_less;
             }
+            else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+                    psci->bracket_greater = pTrigger->test_value;
+                    pnewgtval = &psci->bracket_greater;
+            }
         }
         else if (pTrigger->test_type == XSyncNegativeTransition &&
                  ct != XSyncCounterNeverIncreases) {
@@ -1041,6 +1051,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                     psci->bracket_less = pTrigger->test_value;
                     pnewltval = &psci->bracket_less;
             }
+            else if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+                    psci->bracket_greater = pTrigger->test_value;
+                    pnewgtval = &psci->bracket_greater;
+            }
         }
         else if (pTrigger->test_type == XSyncPositiveTransition &&
                  ct != XSyncCounterNeverDecreases) {
@@ -1055,6 +1070,11 @@ SyncComputeBracketValues(SyncCounter * pCounter)
                     psci->bracket_greater = pTrigger->test_value;
                     pnewgtval = &psci->bracket_greater;
             }
+            else if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
+                     XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+                    psci->bracket_less = pTrigger->test_value;
+                    pnewltval = &psci->bracket_less;
+            }
         }
     }                           /* end for each trigger */
 

commit 06b87aa528d7a739ba20101a1f83b1a428691a01
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Oct 16 10:08:46 2013 +1000

    sync: if the idle time was reset, force alarms to trigger (#70476)
    
    The time between the idle reset and the IdleTimeWakeupHandler to be called is
    indeterminate. Clients with an PositiveTransition or NegativeTransition alarm
    on a low threshold may miss an alarm.
    
    Work around this by keeping a reset flag for each device. When the
    WakeupHandler triggers and the reset flag is set, we force a re-calculation of
    everything and pretend the current idle time is zero. Immediately after is the
    next calculation with the real idle time.
    
    Relatively reproducible test case: Set up a XSyncNegativeTransition alarm for
    a threshold of 1 ms. May trigger, may not.
    
    X.Org Bug 70476 <http://bugs.freedesktop.org/show_bug.cgi?id=70476>
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Keith Packard <keithp@keithp.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index ed891b1..ab46d89 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2686,6 +2686,15 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
 }
 
 static void
+IdleTimeCheckBrackets(SyncCounter *counter, XSyncValue idle, XSyncValue *less, XSyncValue *greater)
+{
+    if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
+        (less && XSyncValueLessOrEqual(idle, *less))) {
+        SyncChangeCounter(counter, idle);
+    }
+}
+
+static void
 IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
 {
     SyncCounter *counter = pCounter;
@@ -2699,10 +2708,24 @@ IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
 
     IdleTimeQueryValue(pCounter, &idle);
 
-    if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
-        (less && XSyncValueLessOrEqual(idle, *less))) {
-        SyncChangeCounter(counter, idle);
+    /*
+      There is no guarantee for the WakeupHandler to be called within a specific
+      timeframe. Idletime may go to 0, but by the time we get here, it may be
+      non-zero and alarms for a pos. transition on 0 won't get triggered.
+      https://bugs.freedesktop.org/show_bug.cgi?id=70476
+      */
+    if (LastEventTimeWasReset(priv->deviceid)) {
+        LastEventTimeToggleResetFlag(priv->deviceid, FALSE);
+        if (!XSyncValueIsZero(idle)) {
+            XSyncValue zero;
+            XSyncIntsToValue(&zero, 0, 0);
+            IdleTimeCheckBrackets(counter, zero, less, greater);
+            less = priv->value_less;
+            greater = priv->value_greater;
+        }
     }
+
+    IdleTimeCheckBrackets(counter, idle, less, greater);
 }
 
 static void
@@ -2720,6 +2743,9 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
                                      IdleTimeWakeupHandler, pCounter);
     }
     else if (!registered && (pbracket_less || pbracket_greater)) {
+        /* Reset flag must be zero so we don't force a idle timer reset on
+           the first wakeup */
+        LastEventTimeToggleResetAll(FALSE);
         RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
                                        IdleTimeWakeupHandler, pCounter);
     }
diff --git a/dix/events.c b/dix/events.c
index c803721..4632bb7 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -262,7 +262,10 @@ InputInfo inputInfo;
 
 EventSyncInfoRec syncEvents;
 
-static TimeStamp lastDeviceEventTime[MAXDEVICES];
+static struct DeviceEventTime {
+    Bool reset;
+    TimeStamp time;
+} lastDeviceEventTime[MAXDEVICES];
 
 /**
  * The root window the given device is currently on.
@@ -1060,8 +1063,11 @@ MonthChangedOrBadTime(CARD32 *ms)
 void
 NoticeTime(const DeviceIntPtr dev, TimeStamp time)
 {
-    lastDeviceEventTime[XIAllDevices] = currentTime;
-    lastDeviceEventTime[dev->id] = currentTime;
+    lastDeviceEventTime[XIAllDevices].time = currentTime;
+    lastDeviceEventTime[dev->id].time = currentTime;
+
+    LastEventTimeToggleResetFlag(dev->id, TRUE);
+    LastEventTimeToggleResetFlag(XIAllDevices, TRUE);
 }
 
 static void
@@ -1085,7 +1091,30 @@ NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev)
 TimeStamp
 LastEventTime(int deviceid)
 {
-    return lastDeviceEventTime[deviceid];
+    return lastDeviceEventTime[deviceid].time;
+}
+
+Bool
+LastEventTimeWasReset(int deviceid)
+{
+    return lastDeviceEventTime[deviceid].reset;
+}
+
+void
+LastEventTimeToggleResetFlag(int deviceid, Bool state)
+{
+    lastDeviceEventTime[deviceid].reset = state;
+}
+
+void
+LastEventTimeToggleResetAll(Bool state)
+{
+    DeviceIntPtr dev;
+    nt_list_for_each_entry(dev, inputInfo.devices, next) {
+        LastEventTimeToggleResetFlag(dev->id, FALSE);
+    }
+    LastEventTimeToggleResetFlag(XIAllDevices, FALSE);
+    LastEventTimeToggleResetFlag(XIAllMasterDevices, FALSE);
 }
 
 /**************************************************************************
@@ -5297,6 +5326,7 @@ InitEvents(void)
 
         dummy.id = i;
         NoticeTime(&dummy, currentTime);
+        LastEventTimeToggleResetFlag(i, FALSE);
     }
 
     syncEvents.replayDev = (DeviceIntPtr) NULL;
diff --git a/include/dix.h b/include/dix.h
index fd2490f..fa7ccd4 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -322,6 +322,12 @@ NoticeEventTime(InternalEvent *ev,
                 DeviceIntPtr dev);
 extern _X_EXPORT TimeStamp
 LastEventTime(int deviceid);
+extern _X_EXPORT Bool
+LastEventTimeWasReset(int deviceid);
+extern _X_EXPORT void
+LastEventTimeToggleResetFlag(int deviceid, Bool state);
+extern _X_EXPORT void
+LastEventTimeToggleResetAll(Bool state);
 
 extern void
 EnqueueEvent(InternalEvent * /* ev */ ,

commit efc1035ca958f2c9d266338a308518a0834b1773
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Oct 16 09:36:01 2013 +1000

    dix: provide accessor methods for the last device event time
    
    And now that we have the accessors, localize it. No functional changes, just
    preparing for a future change.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Keith Packard <keithp@keithp.com>

diff --git a/Xext/saver.c b/Xext/saver.c
index fe81bc4..e06f408 100644
--- a/Xext/saver.c
+++ b/Xext/saver.c
@@ -392,9 +392,7 @@ ScreenSaverFreeSuspend(pointer value, XID id)
             DeviceIntPtr dev;
             UpdateCurrentTimeIf();
             nt_list_for_each_entry(dev, inputInfo.devices, next)
-                lastDeviceEventTime[dev->id] = currentTime;
-            lastDeviceEventTime[XIAllDevices] = currentTime;
-            lastDeviceEventTime[XIAllMasterDevices] = currentTime;
+                NoticeTime(dev, currentTime);
             SetScreenSaverTimer();
         }
     }
@@ -681,7 +679,7 @@ ProcScreenSaverQueryInfo(ClientPtr client)
     pPriv = GetScreenPrivate(pDraw->pScreen);
 
     UpdateCurrentTime();
-    lastInput = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds;
+    lastInput = GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds;
 
     rep = (xScreenSaverQueryInfoReply) {
         .type = X_Reply,
diff --git a/Xext/sync.c b/Xext/sync.c
index f8eb02a..ed891b1 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2605,7 +2605,7 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
     }
     else
         deviceid = XIAllDevices;
-    idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds;
+    idle = GetTimeInMillis() - LastEventTime(deviceid).milliseconds;
     XSyncIntsToValue(pValue_return, idle, 0);
 }
 
diff --git a/dix/events.c b/dix/events.c
index 7a1b1c3..c803721 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -262,6 +262,8 @@ InputInfo inputInfo;
 
 EventSyncInfoRec syncEvents;
 
+static TimeStamp lastDeviceEventTime[MAXDEVICES];
+
 /**
  * The root window the given device is currently on.
  */
@@ -1043,33 +1045,47 @@ XineramaGetCursorScreen(DeviceIntPtr pDev)
 #define TIMESLOP (5 * 60 * 1000)        /* 5 minutes */
 
 static void
-MonthChangedOrBadTime(InternalEvent *ev)
+MonthChangedOrBadTime(CARD32 *ms)
 {
     /* If the ddx/OS is careless about not processing timestamped events from
      * different sources in sorted order, then it's possible for time to go
      * backwards when it should not.  Here we ensure a decent time.
      */
-    if ((currentTime.milliseconds - ev->any.time) > TIMESLOP)
+    if ((currentTime.milliseconds - *ms) > TIMESLOP)
         currentTime.months++;
     else
-        ev->any.time = currentTime.milliseconds;
+        *ms = currentTime.milliseconds;
 }
 
-static void
-NoticeTime(InternalEvent *ev, DeviceIntPtr dev)
+void
+NoticeTime(const DeviceIntPtr dev, TimeStamp time)
 {
-    if (ev->any.time < currentTime.milliseconds)
-        MonthChangedOrBadTime(ev);
-    currentTime.milliseconds = ev->any.time;
     lastDeviceEventTime[XIAllDevices] = currentTime;
     lastDeviceEventTime[dev->id] = currentTime;
 }
 
+static void
+NoticeTimeMillis(const DeviceIntPtr dev, CARD32 *ms)
+{
+    TimeStamp time;
+    if (*ms < currentTime.milliseconds)
+        MonthChangedOrBadTime(ms);
+    time.months = currentTime.months;
+    time.milliseconds = *ms;
+    NoticeTime(dev, time);
+}
+
 void
 NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev)
 {
     if (!syncEvents.playingEvents)
-        NoticeTime(ev, dev);
+        NoticeTimeMillis(dev, &ev->any.time);
+}
+
+TimeStamp
+LastEventTime(int deviceid)
+{
+    return lastDeviceEventTime[deviceid];
 }
 
 /**************************************************************************
@@ -1093,7 +1109,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
     if (!xorg_list_is_empty(&syncEvents.pending))
         tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next);
 
-    NoticeTime((InternalEvent *)event, device);
+    NoticeTimeMillis(device, &ev->any.time);
 
     /* Fix for key repeating bug. */
     if (device->key != NULL && device->key->xkbInfo != NULL &&
@@ -5276,8 +5292,11 @@ InitEvents(void)
     inputInfo.pointer = (DeviceIntPtr) NULL;
 
     for (i = 0; i < MAXDEVICES; i++) {
+        DeviceIntRec dummy;
         memcpy(&event_filters[i], default_filter, sizeof(default_filter));
-        lastDeviceEventTime[i] = currentTime;
+
+        dummy.id = i;
+        NoticeTime(&dummy, currentTime);
     }
 
     syncEvents.replayDev = (DeviceIntPtr) NULL;
diff --git a/dix/globals.c b/dix/globals.c
index 332b91f..ad9145b 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -122,7 +122,6 @@ Bool party_like_its_1989 = FALSE;
 Bool whiteRoot = FALSE;
 
 TimeStamp currentTime;
-TimeStamp lastDeviceEventTime[MAXDEVICES];
 
 int defaultColorVisualClass = -1;
 int monitorResolution = 0;
diff --git a/dix/window.c b/dix/window.c
index cff341b..92df1eb 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -3089,9 +3089,7 @@ dixSaveScreens(ClientPtr client, int on, int mode)
             DeviceIntPtr dev;
             UpdateCurrentTimeIf();
             nt_list_for_each_entry(dev, inputInfo.devices, next)
-                lastDeviceEventTime[dev->id] = currentTime;
-            lastDeviceEventTime[XIAllDevices] = currentTime;
-            lastDeviceEventTime[XIAllMasterDevices] = currentTime;
+                NoticeTime(dev, currentTime);
         }
         SetScreenSaverTimer();
     }
diff --git a/include/dix.h b/include/dix.h
index 171e56e..fd2490f 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -315,8 +315,13 @@ extern _X_EXPORT WindowPtr
 GetSpriteWindow(DeviceIntPtr pDev);
 
 extern _X_EXPORT void
+NoticeTime(const DeviceIntPtr dev,
+           TimeStamp time);
+extern _X_EXPORT void
 NoticeEventTime(InternalEvent *ev,
                 DeviceIntPtr dev);
+extern _X_EXPORT TimeStamp
+LastEventTime(int deviceid);
 
 extern void
 EnqueueEvent(InternalEvent * /* ev */ ,
diff --git a/include/dixstruct.h b/include/dixstruct.h
index 0be7f0e..7711cde 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -144,7 +144,6 @@ typedef struct _WorkQueue {
 } WorkQueueRec;
 
 extern _X_EXPORT TimeStamp currentTime;
-extern _X_EXPORT TimeStamp lastDeviceEventTime[MAXDEVICES];
 
 extern _X_EXPORT int
 CompareTimeStamps(TimeStamp /*a */ ,
diff --git a/os/WaitFor.c b/os/WaitFor.c
index 393890f..c5f4cd7 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -561,7 +561,7 @@ NextDPMSTimeout(INT32 timeout)
 static CARD32
 ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg)
 {
-    INT32 timeout = now - lastDeviceEventTime[XIAllDevices].milliseconds;
+    INT32 timeout = now - LastEventTime(XIAllDevices).milliseconds;
     CARD32 nextTimeout = 0;
 
 #ifdef DPMSExtension
diff --git a/os/xdmcp.c b/os/xdmcp.c
index 0538ac5..11f1133 100644
--- a/os/xdmcp.c
+++ b/os/xdmcp.c
@@ -1391,7 +1391,7 @@ recv_alive_msg(unsigned length)
         if (SessionRunning && AliveSessionID == SessionID) {
             /* backoff dormancy period */
             state = XDM_RUN_SESSION;
-            if ((GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds) >
+            if ((GetTimeInMillis() - LastEventTime(XIAllDevices).milliseconds) >
                 keepaliveDormancy * 1000) {
                 keepaliveDormancy <<= 1;
                 if (keepaliveDormancy > XDM_MAX_DORMANCY)

commit b7c9bd9cf276e92a73be57ff2ed32b47a80f13fb
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Oct 16 09:21:47 2013 +1000

    sync: supply the counter from IdleTimeBlockHandler
    
    The main idletime counter has an initialized deviceid, might as well be
    supplying it properly. Without this, we'd only ever check the XIAllDevices
    counter, so the wait would never be adjusted for the device-specific triggers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Keith Packard <keithp@keithp.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index eaf0637..f8eb02a 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -2624,7 +2624,7 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
         return;
 
     old_idle = counter->value;
-    IdleTimeQueryValue(NULL, &idle);
+    IdleTimeQueryValue(counter, &idle);
     counter->value = idle;      /* push, so CheckTrigger works */
 
     if (less && XSyncValueLessOrEqual(idle, *less)) {

commit 2efe49c1029f959fe80879bcf50df42e8b80451d
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Oct 16 13:01:01 2013 +1000

    sync: always call BracketValues when recalculating upper/lower brackets
    
    Both ServertimeBracketValues and IdleTimeBracketValues copy the value into
    there SysCounter privates. Call it for a NULL set as well, so we don't end up
    with stale pointers and we can remove the block/wakeup handlers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Keith Packard <keithp@keithp.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index f93ac18..eaf0637 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -1058,9 +1058,8 @@ SyncComputeBracketValues(SyncCounter * pCounter)
         }
     }                           /* end for each trigger */
 
-    if (pnewgtval || pnewltval) {
-        (*psci->BracketValues) ((pointer) pCounter, pnewltval, pnewgtval);
-    }
+    (*psci->BracketValues) ((pointer) pCounter, pnewltval, pnewgtval);
+
 }
 
 /*

commit 5c7cfd4c6978834551848e1be62af240102e39b5
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Tue Oct 15 10:11:20 2013 +1000

    sync: compress two if statements
    
    No functional changes, just merges a > and == condition into a >= condition.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Keith Packard <keithp@keithp.com>

diff --git a/Xext/sync.c b/Xext/sync.c
index 9ae5b39..f93ac18 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -1031,42 +1031,29 @@ SyncComputeBracketValues(SyncCounter * pCounter)
         }
         else if (pTrigger->test_type == XSyncNegativeTransition &&
                  ct != XSyncCounterNeverIncreases) {
-            if (XSyncValueGreaterThan(pCounter->value, pTrigger->test_value) &&
-                XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less))
-            {
-                psci->bracket_less = pTrigger->test_value;
-                pnewltval = &psci->bracket_less;
-            }
-            else if (XSyncValueEqual(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueGreaterThan(pTrigger->test_value,
-                                           psci->bracket_less)) {
-                /*
-                 * The value is exactly equal to our threshold.  We want one
-                 * more event in the negative direction to ensure we pick up
-                 * when the value is less than this threshold.
-                 */
-                psci->bracket_less = pTrigger->test_value;
-                pnewltval = &psci->bracket_less;
+            if (XSyncValueGreaterOrEqual(pCounter->value, pTrigger->test_value) &&
+                XSyncValueGreaterThan(pTrigger->test_value, psci->bracket_less)) {
+                    /*
+                     * If the value is exactly equal to our threshold, we want one
+                     * more event in the negative direction to ensure we pick up
+                     * when the value is less than this threshold.
+                     */
+                    psci->bracket_less = pTrigger->test_value;
+                    pnewltval = &psci->bracket_less;
             }
         }
         else if (pTrigger->test_type == XSyncPositiveTransition &&
                  ct != XSyncCounterNeverDecreases) {
-            if (XSyncValueLessThan(pCounter->value, pTrigger->test_value) &&
-                XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater))
-            {
-                psci->bracket_greater = pTrigger->test_value;
-                pnewgtval = &psci->bracket_greater;
-            }
-            else if (XSyncValueEqual(pCounter->value, pTrigger->test_value) &&
-                     XSyncValueLessThan(pTrigger->test_value,
-                                        psci->bracket_greater)) {
-                /*
-                 * The value is exactly equal to our threshold.  We want one
-                 * more event in the positive direction to ensure we pick up
-                 * when the value *exceeds* this threshold.
-                 */
-                psci->bracket_greater = pTrigger->test_value;
-                pnewgtval = &psci->bracket_greater;
+            if (XSyncValueLessOrEqual(pCounter->value, pTrigger->test_value) &&
+                XSyncValueLessThan(pTrigger->test_value, psci->bracket_greater)) {
+                    /*
+                     * If the value is exactly equal to our threshold, we
+                     * want one more event in the positive direction to
+                     * ensure we pick up when the value *exceeds* this
+                     * threshold.
+                     */
+                    psci->bracket_greater = pTrigger->test_value;
+                    pnewgtval = &psci->bracket_greater;
             }
         }
     }                           /* end for each trigger */

commit 73b2660d7273d175d279d22f8ca0c3932a14ff1c
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Mon Sep 16 21:47:16 2013 -0700

    Avoid use-after-free in dix/dixfonts.c: doImageText() [CVE-2013-4396]
    
    Save a pointer to the passed in closure structure before copying it
    and overwriting the *c pointer to point to our copy instead of the
    original.  If we hit an error, once we free(c), reset c to point to
    the original structure before jumping to the cleanup code that
    references *c.
    
    Since one of the errors being checked for is whether the server was
    able to malloc(c->nChars * itemSize), the client can potentially pass
    a number of characters chosen to cause the malloc to fail and the
    error path to be taken, resulting in the read from freed memory.
    
    Since the memory is accessed almost immediately afterwards, and the
    X server is mostly single threaded, the odds of the free memory having
    invalid contents are low with most malloc implementations when not using
    memory debugging features, but some allocators will definitely overwrite
    the memory there, leading to a likely crash.
    
    Reported-by: Pedro Ribeiro <pedrib@gmail.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Reviewed-by: Julien Cristau <jcristau@debian.org>

diff --git a/dix/dixfonts.c b/dix/dixfonts.c
index feb765d..2e34d37 100644
--- a/dix/dixfonts.c
+++ b/dix/dixfonts.c
@@ -1425,6 +1425,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
             GC *pGC;
             unsigned char *data;
             ITclosurePtr new_closure;
+            ITclosurePtr old_closure;
 
             /* We're putting the client to sleep.  We need to
                save some state.  Similar problem to that handled
@@ -1436,12 +1437,14 @@ doImageText(ClientPtr client, ITclosurePtr c)
                 err = BadAlloc;
                 goto bail;
             }
+            old_closure = c;
             *new_closure = *c;
             c = new_closure;
 
             data = malloc(c->nChars * itemSize);
             if (!data) {
                 free(c);
+                c = old_closure;
                 err = BadAlloc;
                 goto bail;
             }
@@ -1452,6 +1455,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
             if (!pGC) {
                 free(c->data);
                 free(c);
+                c = old_closure;
                 err = BadAlloc;
                 goto bail;
             }
@@ -1464,6 +1468,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
                 FreeScratchGC(pGC);
                 free(c->data);
                 free(c);
+                c = old_closure;
                 err = BadAlloc;
                 goto bail;
             }

commit 8afe20d4e34adcfd29bdf43a01d55335ea2c5dba
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Mon Sep 16 21:45:29 2013 -0700

    Update GLX dependencies now that DRI & DRI2 are builtins, not modules
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am
index 9933bc8..3c43640 100644
--- a/hw/xfree86/dixmods/Makefile.am
+++ b/hw/xfree86/dixmods/Makefile.am
@@ -32,7 +32,7 @@ libglx_la_LIBADD = $(top_builddir)/glx/libglx.la $(GLX_SYS_LIBS)
 if AIGLX_DRI_LOADER
 libglx_la_LIBADD += $(top_builddir)/glx/libglxdri.la
 if NO_UNDEFINED
-libglx_la_LIBADD += ../dri/libdri.la ../dri2/libdri2.la
+libglx_la_LIBADD += $(LIBDRM_LIBS) $(PIXMAN_LIBS)
 endif
 endif
 libglx_la_SOURCES = glxmodule.c

commit 2704bdb24a2c7bac65b90e05f1a68438b34ecf58
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Tue Sep 3 22:53:28 2013 -0700

    DMX glxproxy: Don't allocate & copy data just to free it unused
    
    Two functions in the DMX glxproxy code loop over all the backend
    screens, starting at the highest numbered and counting down to
    the lowest.
    
    Previously, for each screen, the code would allocate a buffer
    large enough to read the reply from the backend, copy that reply
    into the buffer, and then if it wasn't the final screen, free it.
    Only the buffer from the final screen is used, to pass on to the
    client in the reply.
    
    This modifies it to just immediately discard the responses from
    the screens as we loop through it, only doing the allocate & copy
    work for the one buffer we pass back to the client.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Reviewed-by: Alex Deucher <aleander.deucher@amd.com>

diff --git a/hw/dmx/glxProxy/glxsingle.c b/hw/dmx/glxProxy/glxsingle.c
index abfb880..679a302 100644
--- a/hw/dmx/glxProxy/glxsingle.c
+++ b/hw/dmx/glxProxy/glxsingle.c
@@ -349,25 +349,29 @@ __glXForwardAllWithReply(__GLXclientState * cl, GLbyte * pc)
          * get the reply from the back-end server
          */
         _XReply(dpy, (xReply *) &be_reply, 0, False);
-        be_buf_size = be_reply.length << 2;
-        if (be_buf_size > 0) {
-            be_buf = (char *) malloc(be_buf_size);
-            if (be_buf) {
-                _XRead(dpy, be_buf, be_buf_size);
+        if (s == from_screen) {
+            /* Save data from last reply to send on to client */
+            be_buf_size = be_reply.length << 2;
+            if (be_buf_size > 0) {
+                be_buf = malloc(be_buf_size);
+                if (be_buf) {
+                    _XRead(dpy, be_buf, be_buf_size);
+                }
+                else {
+                    /* Throw data on the floor */
+                    _XEatDataWords(dpy, be_reply.length);
+                    return BadAlloc;
+                }
             }
-            else {
-                /* Throw data on the floor */
+        }
+        else {
+            /* Just discard data from all replies before the last one */
+            if (be_reply.length > 0)
                 _XEatDataWords(dpy, be_reply.length);
-                return BadAlloc;
-            }
         }
 
         UnlockDisplay(dpy);
         SyncHandle();
-
-        if (s > from_screen && be_buf_size > 0) {
-            free(be_buf);
-        }
     }
 
     /*
diff --git a/hw/dmx/glxProxy/glxvendor.c b/hw/dmx/glxProxy/glxvendor.c
index 50d505c..b475daf 100644
--- a/hw/dmx/glxProxy/glxvendor.c
+++ b/hw/dmx/glxProxy/glxvendor.c
@@ -332,25 +332,29 @@ __glXVForwardAllWithReply(__GLXclientState * cl, GLbyte * pc)
          * get the reply from the back-end server
          */
         _XReply(dpy, (xReply *) &be_reply, 0, False);
-        be_buf_size = be_reply.length << 2;
-        if (be_buf_size > 0) {
-            be_buf = (char *) malloc(be_buf_size);
-            if (be_buf) {
-                _XRead(dpy, be_buf, be_buf_size);
+        if (s == from_screen) {
+            /* Save data from last reply to send on to client */
+            be_buf_size = be_reply.length << 2;
+            if (be_buf_size > 0) {
+                be_buf = malloc(be_buf_size);
+                if (be_buf) {
+                    _XRead(dpy, be_buf, be_buf_size);
+                }
+                else {
+                    /* Throw data on the floor */
+                    _XEatDataWords(dpy, be_reply.length);
+                    return BadAlloc;
+                }
             }
-            else {
-                /* Throw data on the floor */
+        }
+        else {
+            /* Just discard data from all replies before the last one */
+            if (be_reply.length > 0)
                 _XEatDataWords(dpy, be_reply.length);
-                return BadAlloc;
-            }
         }
 
         UnlockDisplay(dpy);
         SyncHandle();
-
-        if (s > from_screen && be_buf_size > 0) {
-            free(be_buf);
-        }
     }
 
     /*

commit 6c06c268adbab63ebe7490489aa030724cbdc54b
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Sun Aug 18 18:02:49 2013 -0700

    Skip damage calls if DamageCreate fails in exa functions
    
    Fixes parfait errors such as:
       Null pointer dereference (CWE 476): Write to null pointer pDamage
            at line 1833 of miext/damage/damage.c in function 'DamageRegister'.
              Function DamageCreate may return constant 'NULL' at line 1775,
                  called at line 232 of exa/exa_migration_mixed.c
                  in function 'exaPrepareAccessReg_mixed'.
              Constant 'NULL' passed into function DamageRegister,
                  argument pDamage, from call at line 237.
              Null pointer introduced at line 1775 of miext/damage/damage.c
                  in function 'DamageCreate'.
       Null pointer dereference (CWE 476): Write to null pointer pDamage
            at line 1833 of miext/damage/damage.c in function 'DamageRegister'.
              Function DamageCreate may return constant 'NULL' at line 1775,
                  called at line 104 of exa/exa_mixed.c
                  in function 'exaCreatePixmap_mixed'.
              Constant 'NULL' passed into function DamageRegister,
                  argument pDamage, from call at line 109.
              Null pointer introduced at line 1775 of miext/damage/damage.c
                  in function 'DamageCreate'.
    
    Checks are similar to handling results of other calls to DamageCreate.
    
    [ This bug was found by the Parfait 1.3.0 bug checking tool.
      http://labs.oracle.com/pls/apex/f?p=labs:49:::::P49_PROJECT_ID:13 ]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>

diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index 5e0bf15..cf66327 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -233,10 +233,13 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
                                                pPixmap->drawable.pScreen,
                                                pPixmap);
 
-            DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
-            /* This ensures that pending damage reflects the current operation. */
-            /* This is used by exa to optimize migration. */
-            DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
+            if (pExaPixmap->pDamage) {
+                DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
+                /* This ensures that pending damage reflects the current
+                 * operation. This is used by exa to optimize migration.
+                 */


Reply to: