[PATCH v2 08/10] dri2: Send events only to known clients

Ville Syrjälä ville.syrjala at nokia.com
Tue Feb 15 03:11:25 PST 2011


On Tue, Feb 15, 2011 at 09:18:36AM +0200, Pauli Nieminen wrote:
> On 14/02/11 21:06 +0200, Ville Syrjälä wrote:
> > On Tue, Feb 08, 2011 at 11:42:54PM +0200, ext Pauli wrote:
> > > From: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
> > > 
> > > If client disconnects and new client gets same id DRI2 events may end to
> > > wrong client. DRI2 reference list can be checked to see if the client
> > > still owns the DRI2Drawable.
> > > 
> > > Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
> > > ---
> > >  hw/xfree86/dri2/dri2.c |   73 +++++++++++++++++++++++++++++++++++------------
> > >  1 files changed, 54 insertions(+), 19 deletions(-)
> > > 
> > > diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
> > > index 9133bb3..c77ac9b 100644
> > > --- a/hw/xfree86/dri2/dri2.c
> > > +++ b/hw/xfree86/dri2/dri2.c
> > > @@ -111,12 +111,16 @@ typedef struct _DRI2Screen {
> > >      ConfigNotifyProcPtr		 ConfigNotify;
> > >  } DRI2ScreenRec;
> > >  
> > > +typedef struct _DRI2ClientEventRec {
> > > +    ClientPtr		client;
> > > +    struct list		link;
> > > +} DRI2ClientEventRec, *DRI2ClientEventPtr;
> > > +
> > >  typedef struct _DRI2SwapCompleteDataRec {
> > >      DRI2BufferPtr	src;
> > >      DRI2BufferPtr	dest;
> > > -    ClientPtr		client;
> > >      void *		data;
> > > -    struct list		link;
> > > +    DRI2ClientEventRec	event;
> > >  } DRI2SwapCompleteDataRec, *DRI2SwapCompleteDataPtr;
> > >  
> > >  static struct list *
> > > @@ -266,7 +270,8 @@ DRI2LookupClientDrawableRef(DRI2DrawablePtr pPriv, ClientPtr client, XID id)
> > >      DRI2DrawableRefPtr ref;
> > >  
> > >      list_for_each_entry(ref, &pPriv->reference_list, link) {
> > > -	if (CLIENT_ID(ref->dri2_id) == client->index && ref->id == id)
> > > +	if (CLIENT_ID(ref->dri2_id) == client->index &&
> > > +		(id == 0 || ref->id == id))
> > >  	    return ref;
> > >      }
> > >      return NULL;
> > > @@ -753,28 +758,41 @@ DRI2CanExchange(DrawablePtr pDraw)
> > >      return FALSE;
> > >  }
> > >  
> > > +static void
> > > +cleanup_client_event(DRI2ClientEventPtr event)
> > > +{
> > > +    if (event->client)
> > > +	list_del(&event->link);
> > > +}
> > > +
> > >  void
> > >  DRI2WaitMSCComplete2(DRI2DrawablePtr pPriv, int frame,
> > >  		     unsigned int tv_sec, unsigned int tv_usec,
> > >  		     void *data)
> > >  {
> > > -    ClientPtr client = data;
> > > +    ClientPtr          blockedClient = pPriv->blockedClient;
> > > +    DRI2ClientEventPtr pEvent = data;
> > > +    ClientPtr          client = pEvent->client;
> > >  
> > > +    pPriv->blockedClient = NULL;
> > > +    pPriv->blockedOnMsc = FALSE;
> > >      pPriv->refcnt--;
> > >  
> > > -    if (pPriv->refcnt <= 0) {
> > > -	DRI2DrawableGone(pPriv, 0);
> > > -	return;
> > > -    }
> > > +    if (client == NULL)
> > > +	goto out;
> > >  
> > >      ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
> > >  			 frame, pPriv->swap_count);
> > >  
> > > -    if (pPriv->blockedClient)
> > > -	AttendClient(pPriv->blockedClient);
> > > +    if (blockedClient)
> > > +	AttendClient(blockedClient);
> > >  
> > > -    pPriv->blockedClient = NULL;
> > > -    pPriv->blockedOnMsc = FALSE;
> > > +out:
> > > +    cleanup_client_event(pEvent);
> > > +    free(pEvent);
> > > +
> > > +    if (pPriv->refcnt <= 0)
> > > +	DRI2DrawableGone(pPriv, 0);
> > >  }
> > >  
> > >  static void
> > > @@ -816,7 +834,7 @@ DRI2WakeClient(ClientPtr client, DRI2DrawablePtr pPriv, int frame,
> > >  static void
> > >  free_swap_complete_data (DRI2DrawablePtr pPriv, DRI2SwapCompleteDataPtr pSwapData)
> > >  {
> > > -    list_del(&pSwapData->link);
> > > +    cleanup_client_event(&pSwapData->event);
> > >      buffer_unref(pPriv, pSwapData->src);
> > >      buffer_unref(pPriv, pSwapData->dest);
> > >      free(pSwapData);
> > > @@ -828,9 +846,10 @@ DRI2SwapComplete2(DRI2DrawablePtr pPriv, int frame,
> > >  		   DRI2SwapEventPtr swap_complete, void *swap_data)
> > >  {
> > >      DRI2SwapCompleteDataPtr pSwapData = swap_data;
> > > -    ClientPtr               client = pSwapData->client;
> > > +    ClientPtr               client = pSwapData->event.client;
> > >      DrawablePtr             pDraw = pPriv->drawable;
> > >      CARD64                  ust = 0;
> > > +    DRI2DrawableRefPtr      ref;
> > >  
> > >      pPriv->swapsPending--;
> > >      pPriv->swap_count++;
> > > @@ -841,6 +860,11 @@ DRI2SwapComplete2(DRI2DrawablePtr pPriv, int frame,
> > >      if (client == NULL)
> > >  	goto out;
> > >  
> > > +    ref = DRI2LookupClientDrawableRef(pPriv, client, 0);
> > > +
> > > +    if (ref == NULL)
> > > +	goto out;
> > 
> > This bit escapes me. pSwapData->event.client is not NULL, so we know
> > the original client is still around. Are we now assuming that
> > DRI2SwapComplete2 was somehow called with an incorrect pSwapData
> > since we have to go looking for the client's ID in the ref list?
> > 
> 
> We still have to check that client haven't called DRIDestroyDrawable. In that
> case client shouldn't receive "random" DRI2 events.

Ah, OK. So there were two changes in the patch. Could be split up I
suppose.

-- 
Ville Syrjälä


More information about the xorg-devel mailing list