[2/3] winebus.sys: Watch for hid raw device addition and removal. (v9)

Aric Stewart aric at codeweavers.com
Mon Oct 3 10:31:04 CDT 2016


Signed-off-by: Aric Stewart <aric at codeweavers.com>

On 10/3/16 6:27 AM, Sebastian Lackner wrote:
> From: Aric Stewart <aric at codeweavers.com>
> 
> Signed-off-by: Aric Stewart <aric at codeweavers.com>
> Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
> ---
> 
> First part of 126774. Besides splitting, I've also done the following changes:
> 
> * Attempt to include both poll.h and sys/poll.h. This is also what is done in other
>   parts of Wine which make use of poll(), like ws2_32.
> * Add a function for device removal, instead of adding code directly to the poll loop.
>   The code for it will follow in the next patch.
> * Move monitor init / event processing code into separate functions - I feel like this
>   makes the code much more readable. It will also be easier to process additional
>   events (for example for shutdown) later.
> * Do not fail initialization when we cannot create a monitor - as pointed out in a
>   previous mails, just using the initial device set might also work in some cases.
> * Do not use a pollfd array yet - so far we only need a single element.
> * Some style improvements.
> 
>  dlls/winebus.sys/bus_udev.c |   80 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 80 insertions(+)
> 
> diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
> index 1f6df6f..dae165d 100644
> --- a/dlls/winebus.sys/bus_udev.c
> +++ b/dlls/winebus.sys/bus_udev.c
> @@ -26,6 +26,12 @@
>  #ifdef HAVE_UNISTD_H
>  # include <unistd.h>
>  #endif
> +#ifdef HAVE_POLL_H
> +# include <poll.h>
> +#endif
> +#ifdef HAVE_SYS_POLL_H
> +# include <sys/poll.h>
> +#endif
>  #ifdef HAVE_LIBUDEV_H
>  # include <libudev.h>
>  #endif
> @@ -129,6 +135,11 @@ static void try_add_device(struct udev_device *dev)
>      HeapFree(GetProcessHeap(), 0, serial);
>  }
>  
> +static void try_remove_device(struct udev_device *dev)
> +{
> +    /* FIXME */
> +}
> +
>  static void build_initial_deviceset(void)
>  {
>      struct udev_enumerate *enumerate;
> @@ -164,13 +175,82 @@ static void build_initial_deviceset(void)
>      udev_enumerate_unref(enumerate);
>  }
>  
> +static struct udev_monitor *create_monitor(struct pollfd *pfd)
> +{
> +    struct udev_monitor *monitor;
> +
> +    monitor = udev_monitor_new_from_netlink(udev_context, "udev");
> +    if (!monitor)
> +    {
> +        WARN("Unable to get udev monitor object\n");
> +        return NULL;
> +    }
> +
> +    if (udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw", NULL) < 0)
> +        WARN("Failed to add subsystem 'hidraw' to monitor\n");
> +
> +    if (udev_monitor_enable_receiving(monitor) < 0)
> +        goto error;
> +
> +    if ((pfd->fd = udev_monitor_get_fd(monitor)) >= 0)
> +    {
> +        pfd->events = POLLIN;
> +        return monitor;
> +    }
> +
> +error:
> +    WARN("Failed to start monitoring\n");
> +    udev_monitor_unref(monitor);
> +    return NULL;
> +}
> +
> +static void process_monitor_event(struct udev_monitor *monitor)
> +{
> +    struct udev_device *dev;
> +    const char *action;
> +
> +    dev = udev_monitor_receive_device(monitor);
> +    if (!dev)
> +    {
> +        FIXME("Failed to get device that has changed\n");
> +        return;
> +    }
> +
> +    action = udev_device_get_action(dev);
> +    TRACE("Received action %s for udev device %s\n", debugstr_a(action),
> +          debugstr_a(udev_device_get_devnode(dev)));
> +
> +    if (!action)
> +        WARN("No action received\n");
> +    else if (strcmp(action, "add") == 0)
> +        try_add_device(dev);
> +    else if (strcmp(action, "remove") == 0)
> +        try_remove_device(dev);
> +    else
> +        WARN("Unhandled action %s\n", debugstr_a(action));
> +
> +    udev_device_unref(dev);
> +}
> +
>  static DWORD CALLBACK deviceloop_thread(void *args)
>  {
> +    struct udev_monitor *monitor;
>      HANDLE init_done = args;
> +    struct pollfd pfd;
>  
> +    monitor = create_monitor(&pfd);
>      build_initial_deviceset();
>      SetEvent(init_done);
>  
> +    while (monitor)
> +    {
> +        if (poll(&pfd, 1, -1) <= 0) continue;
> +        process_monitor_event(monitor);
> +    }
> +
> +    TRACE("Monitor thread exiting\n");
> +    if (monitor)
> +        udev_monitor_unref(monitor);
>      return 0;
>  }
>  
> 



More information about the wine-patches mailing list