[PATCH 2/3] dinput: Use a single list for all acquired devices.

Rémi Bernon rbernon at codeweavers.com
Mon Jun 8 02:47:08 CDT 2020


Instead of going through devices list of dinputs list, and checking
their acquired field, which is not CPU friendly.

This also removes the now unused IDirectInputImpl critical section and
devices list.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/device.c              | 16 +++---
 dlls/dinput/device_private.h      |  2 +-
 dlls/dinput/dinput_main.c         | 88 ++++++++++++++-----------------
 dlls/dinput/dinput_private.h      |  5 +-
 dlls/dinput/joystick_linux.c      |  4 --
 dlls/dinput/joystick_linuxinput.c |  4 --
 dlls/dinput/joystick_osx.c        |  4 --
 dlls/dinput/keyboard.c            |  4 --
 dlls/dinput/mouse.c               |  4 --
 9 files changed, 51 insertions(+), 80 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 51ae349f34e..198e903fc2e 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1001,8 +1001,10 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Acquire(LPDIRECTINPUTDEVICE8W iface)
     res = This->acquired ? S_FALSE : DI_OK;
     This->acquired = 1;
     LeaveCriticalSection(&This->crit);
-    if (res == DI_OK)
-        check_dinput_hooks(iface, TRUE);
+    if (res != DI_OK) return res;
+
+    dinput_hooks_acquire_device(iface);
+    check_dinput_hooks(iface, TRUE);
 
     return res;
 }
@@ -1029,8 +1031,10 @@ HRESULT WINAPI IDirectInputDevice2WImpl_Unacquire(LPDIRECTINPUTDEVICE8W iface)
     res = !This->acquired ? DI_NOEFFECT : DI_OK;
     This->acquired = 0;
     LeaveCriticalSection(&This->crit);
-    if (res == DI_OK)
-        check_dinput_hooks(iface, FALSE);
+    if (res != DI_OK) return res;
+
+    dinput_hooks_unacquire_device(iface);
+    check_dinput_hooks(iface, FALSE);
 
     return res;
 }
@@ -1164,10 +1168,6 @@ ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
     /* Free action mapping */
     HeapFree(GetProcessHeap(), 0, This->action_map);
 
-    EnterCriticalSection( &This->dinput->crit );
-    list_remove( &This->entry );
-    LeaveCriticalSection( &This->dinput->crit );
-
     IDirectInput_Release(&This->dinput->IDirectInput7A_iface);
     This->crit.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection(&This->crit);
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index 23d9e2eebc4..5879409c1de 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -63,7 +63,7 @@ struct IDirectInputDeviceImpl
     GUID                        guid;
     CRITICAL_SECTION            crit;
     IDirectInputImpl           *dinput;
-    struct list                 entry;       /* entry into IDirectInput devices list */
+    struct list                 entry;       /* entry into acquired device list */
     HANDLE                      hEvent;
     DWORD                       dwCoopLevel;
     HWND                        win;
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 5eaa32bd0be..4986e5857b4 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -100,10 +100,29 @@ HINSTANCE DINPUT_instance;
 static BOOL check_hook_thread(void);
 static CRITICAL_SECTION dinput_hook_crit;
 static struct list direct_input_list = LIST_INIT( direct_input_list );
+static struct list acquired_device_list = LIST_INIT( acquired_device_list );
 
 static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwVersion);
 static void uninitialize_directinput_instance(IDirectInputImpl *This);
 
+void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface)
+{
+    IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface);
+
+    EnterCriticalSection( &dinput_hook_crit );
+    list_add_tail( &acquired_device_list, &dev->entry );
+    LeaveCriticalSection( &dinput_hook_crit );
+}
+
+void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface)
+{
+    IDirectInputDeviceImpl *dev = impl_from_IDirectInputDevice8W(iface);
+
+    EnterCriticalSection( &dinput_hook_crit );
+    list_remove( &dev->entry );
+    LeaveCriticalSection( &dinput_hook_crit );
+}
+
 static HRESULT create_directinput_instance(REFIID riid, LPVOID *ppDI, IDirectInputImpl **out)
 {
     IDirectInputImpl *This = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectInputImpl) );
@@ -618,10 +637,6 @@ static HRESULT initialize_directinput_instance(IDirectInputImpl *This, DWORD dwV
         This->dwVersion = dwVersion;
         This->evsequence = 1;
 
-        InitializeCriticalSection( &This->crit );
-        This->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectInputImpl*->crit");
-
-        list_init( &This->devices_list );
         list_init( &This->device_players );
 
         /* Add self to the list of the IDirectInputs */
@@ -657,9 +672,6 @@ static void uninitialize_directinput_instance(IDirectInputImpl *This)
 
         check_hook_thread();
 
-        This->crit.DebugInfo->Spare[0] = 0;
-        DeleteCriticalSection( &This->crit );
-
         This->initialized = FALSE;
     }
 }
@@ -1641,24 +1653,19 @@ HRESULT WINAPI DllUnregisterServer(void)
 
 static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
 {
-    IDirectInputImpl *dinput;
+    IDirectInputDeviceImpl *dev;
     int skip = 0;
 
     if (code != HC_ACTION) return CallNextHookEx( 0, code, wparam, lparam );
 
     EnterCriticalSection( &dinput_hook_crit );
-    LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
+    LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
     {
-        IDirectInputDeviceImpl *dev;
-
-        EnterCriticalSection( &dinput->crit );
-        LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
-            if (dev->acquired && dev->event_proc)
-            {
-                TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
-                skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
-            }
-        LeaveCriticalSection( &dinput->crit );
+        if (dev->event_proc)
+        {
+            TRACE("calling %p->%p (%lx %lx)\n", dev, dev->event_proc, wparam, lparam);
+            skip |= dev->event_proc( &dev->IDirectInputDevice8A_iface, wparam, lparam );
+        }
     }
     LeaveCriticalSection( &dinput_hook_crit );
 
@@ -1667,8 +1674,8 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
 
 static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam )
 {
+    IDirectInputDeviceImpl *dev, *next;
     CWPSTRUCT *msg = (CWPSTRUCT *)lparam;
-    IDirectInputImpl *dinput;
     HWND foreground;
 
     if (code != HC_ACTION || (msg->message != WM_KILLFOCUS &&
@@ -1678,23 +1685,13 @@ static LRESULT CALLBACK callwndproc_proc( int code, WPARAM wparam, LPARAM lparam
     foreground = GetForegroundWindow();
 
     EnterCriticalSection( &dinput_hook_crit );
-
-    LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
+    LIST_FOR_EACH_ENTRY_SAFE( dev, next, &acquired_device_list, IDirectInputDeviceImpl, entry )
     {
-        IDirectInputDeviceImpl *dev;
-
-        EnterCriticalSection( &dinput->crit );
-        LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
+        if (msg->hwnd == dev->win && msg->hwnd != foreground)
         {
-            if (!dev->acquired) continue;
-
-            if (msg->hwnd == dev->win && msg->hwnd != foreground)
-            {
-                TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
-                IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
-            }
+            TRACE( "%p window is not foreground - unacquiring %p\n", dev->win, dev );
+            IDirectInputDevice_Unacquire( &dev->IDirectInputDevice8A_iface );
         }
-        LeaveCriticalSection( &dinput->crit );
     }
     LeaveCriticalSection( &dinput_hook_crit );
 
@@ -1716,7 +1713,7 @@ static DWORD WINAPI hook_thread_proc(void *param)
 
         if (msg.message == WM_USER+0x10)
         {
-            IDirectInputImpl *dinput;
+            IDirectInputDeviceImpl *dev;
             HANDLE finished_event = (HANDLE)msg.lParam;
 
             TRACE( "Processing hook change notification wp:%ld lp:%#lx\n", msg.wParam, msg.lParam );
@@ -1732,22 +1729,15 @@ static DWORD WINAPI hook_thread_proc(void *param)
             EnterCriticalSection( &dinput_hook_crit );
 
             /* Count acquired keyboards and mice*/
-            LIST_FOR_EACH_ENTRY( dinput, &direct_input_list, IDirectInputImpl, entry )
+            LIST_FOR_EACH_ENTRY( dev, &acquired_device_list, IDirectInputDeviceImpl, entry )
             {
-                IDirectInputDeviceImpl *dev;
+                if (!dev->event_proc) continue;
 
-                EnterCriticalSection( &dinput->crit );
-                LIST_FOR_EACH_ENTRY( dev, &dinput->devices_list, IDirectInputDeviceImpl, entry )
-                {
-                    if (!dev->acquired || !dev->event_proc) continue;
-
-                    if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
-                        kbd_cnt++;
-                    else
-                        if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
-                            mice_cnt++;
-                }
-                LeaveCriticalSection( &dinput->crit );
+                if (IsEqualGUID( &dev->guid, &GUID_SysKeyboard ))
+                    kbd_cnt++;
+                else
+                    if (IsEqualGUID( &dev->guid, &GUID_SysMouse ))
+                        mice_cnt++;
             }
             LeaveCriticalSection( &dinput_hook_crit );
 
diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h
index 289b2f1f63d..121c487c2d8 100644
--- a/dlls/dinput/dinput_private.h
+++ b/dlls/dinput/dinput_private.h
@@ -42,12 +42,10 @@ struct IDirectInputImpl
     LONG                        ref;
 
     BOOL                        initialized;
-    CRITICAL_SECTION            crit;
     struct list                 entry;          /* entry into list of all IDirectInputs */
 
     DWORD                       evsequence;     /* unique sequence number for events */
     DWORD                       dwVersion;      /* direct input version number */
-    struct list                 devices_list;   /* list of all created dinput devices */
     struct list                 device_players; /* device instance guid to player name */
 };
 
@@ -71,6 +69,9 @@ extern const struct dinput_device joystick_linux_device DECLSPEC_HIDDEN;
 extern const struct dinput_device joystick_linuxinput_device DECLSPEC_HIDDEN;
 extern const struct dinput_device joystick_osx_device DECLSPEC_HIDDEN;
 
+extern void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface);
+extern void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface);
+
 extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W, BOOL) DECLSPEC_HIDDEN;
 extern void check_dinput_events(void) DECLSPEC_HIDDEN;
 typedef int (*DI_EVENT_PROC)(LPDIRECTINPUTDEVICE8A, WPARAM, LPARAM);
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index afdf659b4a5..2b26eb806d3 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -554,10 +554,6 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
 
     IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
 
-    EnterCriticalSection(&dinput->crit);
-    list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
-    LeaveCriticalSection(&dinput->crit);
-
     newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
     newDevice->generic.devcaps.dwFlags = DIDC_ATTACHED;
 
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index b61913119c8..102de8269b9 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -595,10 +595,6 @@ static JoystickImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput, unsig
 
     IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
 
-    EnterCriticalSection(&dinput->crit);
-    list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
-    LeaveCriticalSection(&dinput->crit);
-
     return newDevice;
 
 failed:
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
index 990f5d1f077..4ec72465500 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -1242,10 +1242,6 @@ static HRESULT alloc_device(REFGUID rguid, IDirectInputImpl *dinput,
 
     IDirectInput_AddRef(&newDevice->generic.base.dinput->IDirectInput7A_iface);
 
-    EnterCriticalSection(&dinput->crit);
-    list_add_tail(&dinput->devices_list, &newDevice->generic.base.entry);
-    LeaveCriticalSection(&dinput->crit);
-
     newDevice->generic.devcaps.dwSize = sizeof(newDevice->generic.devcaps);
     newDevice->generic.devcaps.dwFlags |= DIDC_ATTACHED;
     if (newDevice->generic.base.dinput->dwVersion >= 0x0800)
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index f842f1ca42e..6675a79f84b 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -291,10 +291,6 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
     newDevice->base.data_format.wine_df = df;
     IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
 
-    EnterCriticalSection(&dinput->crit);
-    list_add_tail(&dinput->devices_list, &newDevice->base.entry);
-    LeaveCriticalSection(&dinput->crit);
-
     return newDevice;
 
 failed:
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 08ace2f4e97..abf6fb9599c 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -242,10 +242,6 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
     newDevice->base.data_format.wine_df = df;
     IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
 
-    EnterCriticalSection(&dinput->crit);
-    list_add_tail(&dinput->devices_list, &newDevice->base.entry);
-    LeaveCriticalSection(&dinput->crit);
-
     return newDevice;
 
 failed:
-- 
2.27.0




More information about the wine-devel mailing list