Commit d58055dd authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dinput: Keep a reference on acquired devices while waiting.

parent 5fa11f5f
......@@ -46,10 +46,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
#define INPUT_THREAD_MAX_DEVICES 128
struct input_thread_state
{
UINT events_count;
HANDLE events[128];
UINT devices_count;
struct dinput_device *devices[INPUT_THREAD_MAX_DEVICES];
HANDLE events[INPUT_THREAD_MAX_DEVICES];
};
static inline struct dinput_device *impl_from_IDirectInputDevice8W( IDirectInputDevice8W *iface )
......@@ -247,9 +251,11 @@ static void input_thread_update_device_list( struct input_thread_state *state )
{
if (!device->read_event || !device->vtbl->read) continue;
state->events[count] = device->read_event;
if (++count >= ARRAY_SIZE(state->events)) break;
dinput_device_internal_addref( (state->devices[count] = device) );
if (++count >= INPUT_THREAD_MAX_DEVICES) break;
}
state->events_count = count;
state->devices_count = count;
LeaveCriticalSection( &dinput_hook_crit );
}
......@@ -258,7 +264,7 @@ static DWORD WINAPI dinput_thread_proc( void *params )
HANDLE finished_event, start_event = params;
struct input_thread_state state = {0};
static HHOOK kbd_hook, mouse_hook;
struct dinput_device *impl, *next;
struct dinput_device *device;
DWORD ret;
MSG msg;
......@@ -274,20 +280,13 @@ static DWORD WINAPI dinput_thread_proc( void *params )
if (ret < state.events_count)
{
EnterCriticalSection( &dinput_hook_crit );
LIST_FOR_EACH_ENTRY_SAFE( impl, next, &acquired_device_list, struct dinput_device, entry )
if ((device = state.devices[ret]) && FAILED( device->vtbl->read( &device->IDirectInputDevice8W_iface ) ))
{
if (impl->read_event == state.events[ret])
{
if (FAILED( impl->vtbl->read( &impl->IDirectInputDevice8W_iface ) ))
{
dinput_device_internal_unacquire( &impl->IDirectInputDevice8W_iface );
impl->status = STATUS_UNPLUGGED;
}
break;
}
EnterCriticalSection( &dinput_hook_crit );
dinput_device_internal_unacquire( &device->IDirectInputDevice8W_iface );
LeaveCriticalSection( &dinput_hook_crit );
device->status = STATUS_UNPLUGGED;
}
LeaveCriticalSection( &dinput_hook_crit );
}
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
......@@ -335,12 +334,14 @@ static DWORD WINAPI dinput_thread_proc( void *params )
SetEvent(finished_event);
}
while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] );
input_thread_update_device_list( &state );
}
if (ret != state.events_count) ERR("Unexpected termination, ret %#lx\n", ret);
done:
while (state.devices_count--) dinput_device_internal_release( state.devices[state.devices_count] );
DestroyWindow( di_em_win );
di_em_win = NULL;
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment