[PATCH v2] Allow driver to call DeleteInputDeviceRequest during UnInit

Oldřich Jedlička oldium.pro at seznam.cz
Fri Jan 15 11:33:38 PST 2010


Hi Peter, Simon,

On Friday 15 of January 2010 at 10:40:02, Simon Thum wrote:
> Oldřich Jedlička wrote:
> > When the input driver (like xf86-input-wacom) removes it's devices
> > during a call to UnInit, the CloseDownDevices() cannot handle it. The
> > "next" variable can become a pointer to freed memory.
> > 
> > The patch introduces order-independent device freeing mechanism by
> > remembering the already freed device ids. The devices can reorder any
> > time during freeing. No device will be double-freed - if the removing
> > failed for any reason; some implementations of DeleteInputDeviceRequest
> > don't free the devices already.
> > 
> > Signed-off-by: Oldřich Jedlička <oldium.pro at seznam.cz>
> > ---
> > 
> >  dix/devices.c |   42 +++++++++++++++++++++++++++++++-----------
> >  1 files changed, 31 insertions(+), 11 deletions(-)
> > 
> > diff --git dix/devices.c dix/devices.c
> > index 245a95b..dce0f12 100644
> > --- dix/devices.c
> > +++ dix/devices.c
> > @@ -878,13 +878,41 @@ CloseDevice(DeviceIntPtr dev)
> > 
> >  }
> >  
> >  /**
> > 
> > + * Shut down all devices of one list and free all resources.
> > + */
> > +static
> > +void
> > +CloseListDevices(DeviceIntPtr *listHead)
> > +{
> > +    /* Used to mark devices that we tried to free */
> > +    Bool freedIds[MAXDEVICES] = { 0 };
> 
> This would only work if UnInit()s removals are somehow forced onto
> freedIds. In any case the freed array is a sort of context that's not
> easy to get right. I'm CC'ing Peter, maybe he's got a better idea.

I was looking for an invariant and found a unique device ID. I don't know if 
there is anything better for this purpose.

The closing loop works as long as those conditions are met:

1. There is no device addition during freeing (the device ID could be re-used 
in such case - so that the device would not be freed). I don't know if that is 
even possible.

2. No device gets enabled during the inputInfo.off_devices list closing - the 
device would be moved to inputInfo.devices list which will not be iterated 
again. The current implementation suffers from the same problem.

Alternative solution: I was thinking also about a different solution. Make the 
DeviceInputDeviceRequest return a value (TRUE/FALSE) to indicate successful 
device removal (TRUE=device is not in any of devices/off_devices list). The 
lists (both?) would be iterated until there is no TRUE value returned or both 
lists are empty.

What do you think? Fix-up problems mentioned in Peter's last email, or go on 
with the alternative solution?

Cheers,
Oldřich.

> > +    DeviceIntPtr dev;
> > +
> > +    if (listHead == NULL)
> > +	return;
> > +
> > +    dev = *listHead;
> > +    while (dev != NULL)
> > +    {
> > +        freedIds[dev->id] = TRUE;
> > +        DeleteInputDeviceRequest(dev);
> > +
> > +        dev = *listHead;
> > +        while (dev != NULL && freedIds[dev->id])
> > +        {
> > +            dev = dev->next;
> > +        }
> > +    }
> > +}
> > +
> > +/**
> > 
> >   * Shut down all devices, free all resources, etc.
> >   * Only useful if you're shutting down the server!
> >   */
> >  
> >  void
> >  CloseDownDevices(void)
> >  {
> > 
> > -    DeviceIntPtr dev, next;
> > +    DeviceIntPtr dev;
> > 
> >      /* Float all SDs before closing them. Note that at this point
> >      resources
> >      
> >       * (e.g. cursors) have been freed already, so we can't just call
> > 
> > @@ -897,16 +925,8 @@ CloseDownDevices(void)
> > 
> >              dev->u.master = NULL;
> >      
> >      }
> > 
> > -    for (dev = inputInfo.devices; dev; dev = next)
> > -    {
> > -	next = dev->next;
> > -        DeleteInputDeviceRequest(dev);
> > -    }
> > -    for (dev = inputInfo.off_devices; dev; dev = next)
> > -    {
> > -	next = dev->next;
> > -        DeleteInputDeviceRequest(dev);
> > -    }
> > +    CloseListDevices(&inputInfo.devices);
> > +    CloseListDevices(&inputInfo.off_devices);
> > 
> >      CloseDevice(inputInfo.pointer);
> >      CloseDevice(inputInfo.keyboard);
> 
> _______________________________________________
> xorg-devel mailing list
> xorg-devel at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-devel


More information about the xorg-devel mailing list