[PATCH evdev] Use the server's device list for duplicate detection (#78309)

Hans de Goede hdegoede at redhat.com
Tue May 6 00:03:55 PDT 2014


Hi,

On 05/06/2014 02:43 AM, Peter Hutterer wrote:
> EvdevAddDevice/EvdevRemoveDevice keep a reference to the device to detect
> duplicate devices based on the dev_t.
> 
> EvdevAddDevices was called during PreInit, EvdevRemoveDevice was called during
> DEVICE_CLOSE. That makes it imbalanced if the device succeeds PreInit but the
> server skips everything else because MAX_DEVICES is exceeded. So for all
> devices after MAX_DEVICES, we'd add a reference but never remove it,
> eventually reading/writing past evdev_devices.
> 
> The server keeps the list of devices for us anyway, so remove the copy of all
> the pointers and instead run through the device list the server gives us.
> 
> X.Org Bug 78309 <http://bugs.freedesktop.org/show_bug.cgi?id=78309>
> 
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

Looks good:

Reviewed-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans

> ---
>  src/evdev.c | 74 +++++++++++--------------------------------------------------
>  1 file changed, 13 insertions(+), 61 deletions(-)
> 
> diff --git a/src/evdev.c b/src/evdev.c
> index 6175015..30f809b 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -68,11 +68,6 @@
>  /* removed from server, purge when dropping support for server 1.10 */
>  #define XI86_SEND_DRAG_EVENTS   0x08
>  
> -#ifndef MAXDEVICES
> -#include <inputstr.h> /* for MAX_DEVICES */
> -#define MAXDEVICES MAX_DEVICES
> -#endif
> -
>  #define ArrayLength(a) (sizeof(a) / (sizeof((a)[0])))
>  
>  #define MIN_KEYCODE 8
> @@ -146,11 +141,6 @@ static Atom prop_device;
>  static Atom prop_virtual;
>  static Atom prop_scroll_dist;
>  
> -/* All devices the evdev driver has allocated and knows about.
> - * MAXDEVICES is safe as null-terminated array, as two devices (VCP and VCK)
> - * cannot be used by evdev, leaving us with a space of 2 at the end. */
> -static EvdevPtr evdev_devices[MAXDEVICES] = {NULL};
> -
>  static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
>  {
>      InputInfoPtr pInfo;
> @@ -216,60 +206,25 @@ static BOOL
>  EvdevIsDuplicate(InputInfoPtr pInfo)
>  {
>      EvdevPtr pEvdev = pInfo->private;
> -    EvdevPtr* dev   = evdev_devices;
> +    InputInfoPtr d;
>  
> -    if (pEvdev->min_maj)
> +    nt_list_for_each_entry(d, xf86FirstLocalDevice(), next)
>      {
> -        while(*dev)
> -        {
> -            if ((*dev) != pEvdev &&
> -                (*dev)->min_maj &&
> -                (*dev)->min_maj == pEvdev->min_maj)
> -                return TRUE;
> -            dev++;
> -        }
> +        EvdevPtr e;
> +
> +        if (strcmp(d->drv->driverName, "evdev") != 0)
> +            continue;
> +
> +        e = (EvdevPtr)d->private;
> +        if (e != pEvdev &&
> +            e->min_maj &&
> +            e->min_maj == pEvdev->min_maj)
> +            return TRUE;
>      }
> +
>      return FALSE;
>  }
>  
> -/**
> - * Add to internal device list.
> - */
> -static void
> -EvdevAddDevice(InputInfoPtr pInfo)
> -{
> -    EvdevPtr pEvdev = pInfo->private;
> -    EvdevPtr* dev = evdev_devices;
> -
> -    while(*dev)
> -        dev++;
> -
> -    *dev = pEvdev;
> -}
> -
> -/**
> - * Remove from internal device list.
> - */
> -static void
> -EvdevRemoveDevice(InputInfoPtr pInfo)
> -{
> -    EvdevPtr pEvdev = pInfo->private;
> -    EvdevPtr *dev   = evdev_devices;
> -    int count       = 0;
> -
> -    while(*dev)
> -    {
> -        count++;
> -        if (*dev == pEvdev)
> -        {
> -            memmove(dev, dev + 1,
> -                    sizeof(evdev_devices) - (count * sizeof(EvdevPtr)));
> -            break;
> -        }
> -        dev++;
> -    }
> -}
> -
>  static BOOL
>  EvdevDeviceIsVirtual(const char* devicenode)
>  {
> @@ -2026,7 +1981,6 @@ EvdevProc(DeviceIntPtr device, int what)
>  	xf86IDrvMsg(pInfo, X_INFO, "Close\n");
>          EvdevCloseDevice(pInfo);
>          EvdevFreeMasks(pEvdev);
> -        EvdevRemoveDevice(pInfo);
>          pEvdev->min_maj = 0;
>  	break;
>  
> @@ -2659,8 +2613,6 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
>                                           pInfo->type_name);
>      pInfo->type_name = pEvdev->type_name;
>  
> -    EvdevAddDevice(pInfo);
> -
>      if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
>      {
>          EvdevMBEmuPreInit(pInfo);
> 


More information about the xorg-devel mailing list