[PATCH v2] Allow driver to call DeleteInputDeviceRequest during UnInit

Simon Thum simon.thum at gmx.de
Sat Jan 16 01:00:55 PST 2010


Oldřich Jedlička wrote:
> 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.
So my workflow was: mutter around -> leave house -> get struck by how
the code is correct -> be offline.

I just failed to see the gist of the v2 patch. Sorry for the noise. Just
fix the naming as peter said, and of course it's:
Reviewed-by: Simon Thum <simon.thum at gmx.de>

As for the alternative solution you outlined below, I don't think it
makes sense to allow for device additions while closing down, especially
since config_fini() is called earlier in shutdown.

Cheers,

Simon

> 
> 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