dri2: Use the work queue to manage client sleeps
In commit e43abdce96
Author: Chris Wilson <chris@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.
Tested-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
b3e9c534e2
commit
eddf848c44
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue