[PATCH xserver] dri2: Use the work queue to manage client sleeps

Adam Jackson ajax at redhat.com
Wed Feb 10 16:51:18 UTC 2016


In  commit e43abdce964f5ed9689cf908af8c305b39a5dd36
    Author: Chris Wilson <chris at chris-wilson.co.uk>
    Date:   Wed Feb 3 09:54:46 2016 +0000

        dri2: Unblock Clients on Drawable release

we try to wake up any blocked clients at drawable destruction. But by
the time we get there, CloseDownConnection has already torn down state
that AttendClient wants to modify.

Using ClientSleep instead of IgnoreClient puts a wakeup function on a
workqueue, and the queue will be cleared for us in CloseDownClient
before (non-neverretain) resource teardown.

Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 hw/xfree86/dri2/dri2.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index dfc2f49..30ac1a7 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -260,8 +260,7 @@ DRI2SwapLimit(DrawablePtr pDraw, int swap_limit)
 
     if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
         if (pPriv->blockedClient) {
-            AttendClient(pPriv->blockedClient);
-            pPriv->blockedClient = NULL;
+            ClientSignal(pPriv->blockedClient);
         }
     }
 
@@ -414,7 +413,7 @@ DRI2DrawableGone(void *p, XID id)
     }
 
     if (pPriv->blockedClient)
-        AttendClient(pPriv->blockedClient);
+        ClientSignal(pPriv->blockedClient);
 
     free(pPriv);
 
@@ -690,6 +689,15 @@ DRI2InvalidateDrawable(DrawablePtr pDraw)
         ref->invalidate(pDraw, ref->priv, ref->id);
 }
 
+static Bool
+dri2ClientWake(ClientPtr client, void *closure)
+{
+    DRI2DrawablePtr pPriv = closure;
+    ClientWakeup(client);
+    pPriv->blockedClient = NULL;
+    return TRUE;
+}
+
 /*
  * In the direct rendered case, we throttle the clients that have more
  * than their share of outstanding swaps (and thus busy buffers) when a
@@ -710,7 +718,7 @@ DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
     if ((pPriv->swapsPending >= pPriv->swap_limit) && !pPriv->blockedClient) {
         ResetCurrentRequest(client);
         client->sequence--;
-        IgnoreClient(client);
+        ClientSleep(client, dri2ClientWake, pPriv);
         pPriv->blockedClient = client;
         return TRUE;
     }
@@ -722,7 +730,7 @@ static void
 __DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
 {
     if (pPriv->blockedClient == NULL) {
-        IgnoreClient(client);
+        ClientSleep(client, dri2ClientWake, pPriv);
         pPriv->blockedClient = client;
     }
 }
@@ -971,9 +979,8 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
                          frame, pPriv->swap_count);
 
     if (pPriv->blockedClient)
-        AttendClient(pPriv->blockedClient);
+        ClientSignal(pPriv->blockedClient);
 
-    pPriv->blockedClient = NULL;
     pPriv->blockedOnMsc = FALSE;
 }
 
@@ -983,7 +990,7 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
 {
     ScreenPtr pScreen = pDraw->pScreen;
     DRI2DrawablePtr pPriv;
-
+t
     pPriv = DRI2GetDrawable(pDraw);
     if (pPriv == NULL) {
         xf86DrvMsg(pScreen->myNum, X_ERROR,
@@ -1003,14 +1010,11 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
         ProcDRI2WaitMSCReply(client, ((CARD64) tv_sec * 1000000) + tv_usec,
                              frame, pPriv->swap_count);
         pPriv->target_sbc = -1;
-
-        AttendClient(pPriv->blockedClient);
-        pPriv->blockedClient = NULL;
+        ClientSignal(pPriv->blockedClient);
     }
     else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
         if (pPriv->blockedClient) {
-            AttendClient(pPriv->blockedClient);
-            pPriv->blockedClient = NULL;
+            ClientSignal(pPriv->blockedClient);
         }
     }
 }
-- 
2.5.0



More information about the xorg-devel mailing list