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

Sebastian Lackner sebastian at fds-team.de
Mon Oct 3 06:27:36 CDT 2016


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;
 }
 
-- 
2.9.0



More information about the wine-patches mailing list