Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
44348970
Commit
44348970
authored
May 11, 2022
by
Zebediah Figura
Committed by
Alexandre Julliard
Jul 05, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wineusb.sys: Spawn a separate thread to consume Unix library events.
parent
4676273b
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
95 additions
and
4 deletions
+95
-4
wineusb.c
dlls/wineusb.sys/wineusb.c
+95
-4
No files found.
dlls/wineusb.sys/wineusb.c
View file @
44348970
...
...
@@ -20,6 +20,7 @@
#include <assert.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <pthread.h>
#include <libusb.h>
...
...
@@ -107,6 +108,71 @@ static DEVICE_OBJECT *bus_fdo, *bus_pdo;
static
libusb_hotplug_callback_handle
hotplug_cb_handle
;
static
pthread_cond_t
event_cond
=
PTHREAD_COND_INITIALIZER
;
static
pthread_mutex_t
event_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
enum
usb_event_type
{
USB_EVENT_SHUTDOWN
,
};
struct
usb_event
{
enum
usb_event_type
type
;
};
static
struct
usb_event
*
usb_events
;
static
size_t
usb_event_count
,
usb_events_capacity
;
static
bool
array_reserve
(
void
**
elements
,
size_t
*
capacity
,
size_t
count
,
size_t
size
)
{
unsigned
int
new_capacity
,
max_capacity
;
void
*
new_elements
;
if
(
count
<=
*
capacity
)
return
true
;
max_capacity
=
~
(
size_t
)
0
/
size
;
if
(
count
>
max_capacity
)
return
false
;
new_capacity
=
max
(
4
,
*
capacity
);
while
(
new_capacity
<
count
&&
new_capacity
<=
max_capacity
/
2
)
new_capacity
*=
2
;
if
(
new_capacity
<
count
)
new_capacity
=
max_capacity
;
if
(
!
(
new_elements
=
realloc
(
*
elements
,
new_capacity
*
size
)))
return
false
;
*
elements
=
new_elements
;
*
capacity
=
new_capacity
;
return
true
;
}
static
void
queue_event
(
const
struct
usb_event
*
event
)
{
pthread_mutex_lock
(
&
event_mutex
);
if
(
array_reserve
((
void
**
)
&
usb_events
,
&
usb_events_capacity
,
usb_event_count
+
1
,
sizeof
(
*
usb_events
)))
usb_events
[
usb_event_count
++
]
=
*
event
;
else
ERR
(
"Failed to queue event.
\n
"
);
pthread_mutex_unlock
(
&
event_mutex
);
pthread_cond_signal
(
&
event_cond
);
}
static
void
get_event
(
struct
usb_event
*
event
)
{
pthread_mutex_lock
(
&
event_mutex
);
while
(
!
usb_event_count
)
pthread_cond_wait
(
&
event_cond
,
&
event_mutex
);
*
event
=
usb_events
[
0
];
if
(
--
usb_event_count
)
memmove
(
usb_events
,
usb_events
+
1
,
usb_event_count
*
sizeof
(
*
usb_events
));
pthread_mutex_unlock
(
&
event_mutex
);
}
static
void
destroy_unix_device
(
struct
unix_device
*
unix_device
)
{
pthread_mutex_lock
(
&
unix_device_mutex
);
...
...
@@ -293,7 +359,7 @@ static void remove_usb_device(libusb_device *libusb_device)
}
static
BOOL
thread_shutdown
;
static
HANDLE
event_thread
;
static
HANDLE
libusb_event_thread
,
event_thread
;
static
int
LIBUSB_CALL
hotplug_cb
(
libusb_context
*
context
,
libusb_device
*
device
,
libusb_hotplug_event
event
,
void
*
user_data
)
...
...
@@ -306,11 +372,12 @@ static int LIBUSB_CALL hotplug_cb(libusb_context *context, libusb_device *device
return
0
;
}
static
DWORD
CALLBACK
event_thread_proc
(
void
*
arg
)
static
DWORD
CALLBACK
libusb_
event_thread_proc
(
void
*
arg
)
{
static
const
struct
usb_event
shutdown_event
=
{.
type
=
USB_EVENT_SHUTDOWN
};
int
ret
;
TRACE
(
"Starting event thread.
\n
"
);
TRACE
(
"Starting
libusb
event thread.
\n
"
);
while
(
!
thread_shutdown
)
{
...
...
@@ -318,10 +385,31 @@ static DWORD CALLBACK event_thread_proc(void *arg)
ERR
(
"Error handling events: %s
\n
"
,
libusb_strerror
(
ret
));
}
TRACE
(
"Shutting down event thread.
\n
"
);
queue_event
(
&
shutdown_event
);
TRACE
(
"Shutting down libusb event thread.
\n
"
);
return
0
;
}
static
DWORD
CALLBACK
event_thread_proc
(
void
*
arg
)
{
struct
usb_event
event
;
TRACE
(
"Starting client event thread.
\n
"
);
for
(;;)
{
get_event
(
&
event
);
switch
(
event
.
type
)
{
case
USB_EVENT_SHUTDOWN
:
TRACE
(
"Shutting down client event thread.
\n
"
);
return
0
;
}
}
}
static
NTSTATUS
fdo_pnp
(
IRP
*
irp
)
{
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
...
...
@@ -391,6 +479,8 @@ static NTSTATUS fdo_pnp(IRP *irp)
libusb_hotplug_deregister_callback
(
NULL
,
hotplug_cb_handle
);
thread_shutdown
=
TRUE
;
libusb_interrupt_event_handler
(
NULL
);
WaitForSingleObject
(
libusb_event_thread
,
INFINITE
);
CloseHandle
(
libusb_event_thread
);
WaitForSingleObject
(
event_thread
,
INFINITE
);
CloseHandle
(
event_thread
);
...
...
@@ -1007,6 +1097,7 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path)
return
STATUS_UNSUCCESSFUL
;
}
libusb_event_thread
=
CreateThread
(
NULL
,
0
,
libusb_event_thread_proc
,
NULL
,
0
,
NULL
);
event_thread
=
CreateThread
(
NULL
,
0
,
event_thread_proc
,
NULL
,
0
,
NULL
);
driver
->
DriverExtension
->
AddDevice
=
driver_add_device
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment