[PATCH v3 2/7] winebus.sys: Create the UDEV bus thread in main.c.
Rémi Bernon
rbernon at codeweavers.com
Mon Aug 23 03:49:37 CDT 2021
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/winebus.sys/bus.h | 6 +-
dlls/winebus.sys/bus_udev.c | 130 ++++++++++++++++--------------------
dlls/winebus.sys/main.c | 15 ++++-
3 files changed, 75 insertions(+), 76 deletions(-)
diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
index c5b93b769c9..6dc95a5b803 100644
--- a/dlls/winebus.sys/bus.h
+++ b/dlls/winebus.sys/bus.h
@@ -28,15 +28,17 @@
typedef int(*enum_func)(DEVICE_OBJECT *device, void *context);
/* Buses */
-NTSTATUS udev_driver_init(void) DECLSPEC_HIDDEN;
NTSTATUS iohid_driver_init(void) DECLSPEC_HIDDEN;
-void udev_driver_unload( void ) DECLSPEC_HIDDEN;
void iohid_driver_unload( void ) DECLSPEC_HIDDEN;
extern NTSTATUS sdl_bus_init(void *) DECLSPEC_HIDDEN;
extern NTSTATUS sdl_bus_wait(void *) DECLSPEC_HIDDEN;
extern NTSTATUS sdl_bus_stop(void *) DECLSPEC_HIDDEN;
+extern NTSTATUS udev_bus_init(void *) DECLSPEC_HIDDEN;
+extern NTSTATUS udev_bus_wait(void *) DECLSPEC_HIDDEN;
+extern NTSTATUS udev_bus_stop(void *) DECLSPEC_HIDDEN;
+
/* Native device function table */
typedef struct
{
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 77a242a6087..67d00670a26 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -88,10 +88,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
WINE_DECLARE_DEBUG_CHANNEL(hid_report);
static struct udev *udev_context = NULL;
+static struct udev_monitor *udev_monitor;
static DWORD disable_hidraw = 0;
static DWORD disable_input = 0;
-static HANDLE deviceloop_handle;
static int deviceloop_control[2];
+static int udev_monitor_fd;
static const WCHAR hidraw_busidW[] = {'H','I','D','R','A','W',0};
static const WCHAR lnxev_busidW[] = {'L','N','X','E','V',0};
@@ -1210,7 +1211,7 @@ static void build_initial_deviceset(void)
udev_enumerate_unref(enumerate);
}
-static struct udev_monitor *create_monitor(struct pollfd *pfd)
+static struct udev_monitor *create_monitor(int *fd)
{
struct udev_monitor *monitor;
int systems = 0;
@@ -1247,11 +1248,8 @@ static struct udev_monitor *create_monitor(struct pollfd *pfd)
if (udev_monitor_enable_receiving(monitor) < 0)
goto error;
- if ((pfd->fd = udev_monitor_get_fd(monitor)) >= 0)
- {
- pfd->events = POLLIN;
+ if ((*fd = udev_monitor_get_fd(monitor)) >= 0)
return monitor;
- }
error:
WARN("Failed to start monitoring\n");
@@ -1287,51 +1285,8 @@ static void process_monitor_event(struct udev_monitor *monitor)
udev_device_unref(dev);
}
-static DWORD CALLBACK deviceloop_thread(void *args)
-{
- struct udev_monitor *monitor;
- HANDLE init_done = args;
- struct pollfd pfd[2];
-
- pfd[1].fd = deviceloop_control[0];
- pfd[1].events = POLLIN;
- pfd[1].revents = 0;
-
- monitor = create_monitor(&pfd[0]);
- build_initial_deviceset();
- SetEvent(init_done);
-
- while (monitor)
- {
- if (poll(pfd, 2, -1) <= 0) continue;
- if (pfd[1].revents) break;
- process_monitor_event(monitor);
- }
-
- TRACE("Monitor thread exiting\n");
- if (monitor)
- udev_monitor_unref(monitor);
- return 0;
-}
-
-void udev_driver_unload( void )
-{
- TRACE("Unload Driver\n");
-
- if (!deviceloop_handle)
- return;
-
- write(deviceloop_control[1], "q", 1);
- WaitForSingleObject(deviceloop_handle, INFINITE);
- close(deviceloop_control[0]);
- close(deviceloop_control[1]);
- CloseHandle(deviceloop_handle);
-}
-
-NTSTATUS udev_driver_init(void)
+NTSTATUS udev_bus_init(void *args)
{
- HANDLE events[2];
- DWORD result;
static const WCHAR hidraw_disabledW[] = {'D','i','s','a','b','l','e','H','i','d','r','a','w',0};
static const UNICODE_STRING hidraw_disabled = {sizeof(hidraw_disabledW) - sizeof(WCHAR), sizeof(hidraw_disabledW), (WCHAR*)hidraw_disabledW};
static const WCHAR input_disabledW[] = {'D','i','s','a','b','l','e','I','n','p','u','t',0};
@@ -1339,13 +1294,13 @@ NTSTATUS udev_driver_init(void)
if (pipe(deviceloop_control) != 0)
{
- ERR("Control pipe creation failed\n");
+ ERR("UDEV control pipe creation failed\n");
return STATUS_UNSUCCESSFUL;
}
if (!(udev_context = udev_new()))
{
- ERR("Can't create udev object\n");
+ ERR("UDEV object creation failed\n");
goto error;
}
@@ -1359,46 +1314,75 @@ NTSTATUS udev_driver_init(void)
TRACE("UDEV input devices disabled in registry\n");
#endif
- if (!(events[0] = CreateEventW(NULL, TRUE, FALSE, NULL)))
- goto error;
- if (!(events[1] = CreateThread(NULL, 0, deviceloop_thread, events[0], 0, NULL)))
+ if (!(udev_monitor = create_monitor(&udev_monitor_fd)))
{
- CloseHandle(events[0]);
+ ERR("UDEV monitor creation failed\n");
goto error;
}
- result = WaitForMultipleObjects(2, events, FALSE, INFINITE);
- CloseHandle(events[0]);
- if (result == WAIT_OBJECT_0)
- {
- deviceloop_handle = events[1];
- TRACE("Initialization successful\n");
- return STATUS_SUCCESS;
- }
- CloseHandle(events[1]);
+ build_initial_deviceset();
+ return STATUS_SUCCESS;
error:
- ERR("Failed to initialize udev device thread\n");
+ if (udev_context) udev_unref(udev_context);
+ udev_context = NULL;
close(deviceloop_control[0]);
close(deviceloop_control[1]);
- if (udev_context)
+ return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS udev_bus_wait(void *args)
+{
+ struct pollfd pfd[2];
+
+ pfd[0].fd = udev_monitor_fd;
+ pfd[0].events = POLLIN;
+ pfd[0].revents = 0;
+ pfd[1].fd = deviceloop_control[0];
+ pfd[1].events = POLLIN;
+ pfd[1].revents = 0;
+
+ while (1)
{
- udev_unref(udev_context);
- udev_context = NULL;
+ if (poll(pfd, 2, -1) <= 0) continue;
+ if (pfd[1].revents) break;
+ process_monitor_event(udev_monitor);
}
- return STATUS_UNSUCCESSFUL;
+
+ TRACE("UDEV main loop exiting\n");
+ udev_monitor_unref(udev_monitor);
+ udev_unref(udev_context);
+ udev_context = NULL;
+ close(deviceloop_control[0]);
+ close(deviceloop_control[1]);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS udev_bus_stop(void *args)
+{
+ if (!udev_context) return STATUS_SUCCESS;
+ write(deviceloop_control[1], "q", 1);
+ return STATUS_SUCCESS;
}
#else
-NTSTATUS udev_driver_init(void)
+NTSTATUS udev_bus_init(void *args)
+{
+ WARN("UDEV support not compiled in!\n");
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS udev_bus_wait(void *args)
{
+ WARN("UDEV support not compiled in!\n");
return STATUS_NOT_IMPLEMENTED;
}
-void udev_driver_unload( void )
+NTSTATUS udev_bus_stop(void *args)
{
- TRACE("Stub: Unload Driver\n");
+ WARN("UDEV support not compiled in!\n");
+ return STATUS_NOT_IMPLEMENTED;
}
#endif /* HAVE_UDEV */
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 6be5e677bba..505fc131be4 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -686,6 +686,19 @@ static NTSTATUS sdl_driver_init(void)
return bus_main_thread_start(&bus);
}
+static NTSTATUS udev_driver_init(void)
+{
+ static const WCHAR bus_name[] = {'U','D','E','V',0};
+ struct bus_main_params bus =
+ {
+ .name = bus_name,
+ .init_func = udev_bus_init,
+ .wait_func = udev_bus_wait,
+ };
+
+ return bus_main_thread_start(&bus);
+}
+
static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
{
static const WCHAR SDL_enabledW[] = {'E','n','a','b','l','e',' ','S','D','L',0};
@@ -714,9 +727,9 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IRP_MN_REMOVE_DEVICE:
- udev_driver_unload();
iohid_driver_unload();
sdl_bus_stop(NULL);
+ udev_bus_stop(NULL);
WaitForMultipleObjects(bus_count, bus_thread, TRUE, INFINITE);
while (bus_count--) CloseHandle(bus_thread[bus_count]);
--
2.33.0
More information about the wine-devel
mailing list