Registering only one reference per client avoids invalidate event storm for misbehaving client that calls DRI2CreateDrawable multiple times for same drawable. Each DRI2CreateDrawable creates a new reference. Invalidating drawable then send an event for each reference. This will result client receives multiple events.
This patch is split out from DRI2DestroyDrawable. I originally tough this would be required for destroy but revisiting the patch made me understand that this is not required. Signed-off-by: Pauli Nieminen <[email protected]> --- dri2 specification: "Note that the server is only required to warn the client once about this condition, until the client takes care of bringing them back up-to-date with another GetBuffers request." But if this is not wanted functionality in server then I will be happy to drop this patch. hw/xfree86/dri2/dri2.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 75af3ea..410cdde 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -193,6 +193,7 @@ DRI2AllocateDrawable(DrawablePtr pDraw) typedef struct DRI2DrawableRefRec { XID id; XID dri2_id; + int refcnt; DRI2InvalidateProcPtr invalidate; void *priv; struct list link; @@ -229,6 +230,7 @@ DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id, ref->id = id; ref->dri2_id = dri2_id; + ref->refcnt = 1; ref->invalidate = invalidate; ref->priv = priv; list_add(&ref->link, &pPriv->reference_list); @@ -253,6 +255,7 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id, DRI2InvalidateProcPtr invalidate, void *priv) { DRI2DrawablePtr pPriv; + DRI2DrawableRefPtr ref; XID dri2_id; int rc; @@ -261,6 +264,11 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id, pPriv = DRI2AllocateDrawable(pDraw); if (pPriv == NULL) return BadAlloc; + ref = DRI2FindClientDrawableRef(client, pPriv); + if (ref) { + ref->refcnt++; + return Success; + } dri2_id = FakeClientID(client->index); rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv); @@ -284,7 +292,8 @@ DRI2DestroyDrawable(ClientPtr client, DrawablePtr pDraw, XID id) if (!ref) return BadDrawable; - FreeResourceByType(ref->dri2_id, dri2DrawableRes, FALSE); + if (--ref->refcnt == 0) + FreeResourceByType(ref->dri2_id, dri2DrawableRes, FALSE); return Success; } -- 1.7.0.4 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
