Rémi Bernon : dinput: Add a release callback for internal refcount handling.

Alexandre Julliard julliard at winehq.org
Wed Oct 20 15:58:41 CDT 2021


Module: wine
Branch: master
Commit: 7ccf07ae8f16d83a012673904fafcc4e9f6ecf8b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=7ccf07ae8f16d83a012673904fafcc4e9f6ecf8b

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Wed Oct 20 11:29:33 2021 +0200

dinput: Add a release callback for internal refcount handling.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dinput/device.c         | 30 ++++++++++++++-------
 dlls/dinput/device_private.h |  2 ++
 dlls/dinput/joystick_hid.c   | 62 +++++++++++++++++---------------------------
 dlls/dinput/keyboard.c       |  1 +
 dlls/dinput/mouse.c          |  1 +
 5 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index ef77826ce25..8858bfa26bb 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1049,15 +1049,11 @@ HRESULT WINAPI IDirectInputDevice2WImpl_SetEventNotification(LPDIRECTINPUTDEVICE
     return DI_OK;
 }
 
-
-ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
+void direct_input_device_destroy( IDirectInputDevice8W *iface )
 {
     IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
-    ULONG ref = InterlockedDecrement(&(This->ref));
-
-    TRACE("(%p) ref %d\n", This, ref);
 
-    if (ref) return ref;
+    TRACE( "iface %p.\n", iface );
 
     IDirectInputDevice_Unacquire(iface);
     /* Reset the FF state, free all effects, etc */
@@ -1078,6 +1074,20 @@ ULONG WINAPI IDirectInputDevice2WImpl_Release(LPDIRECTINPUTDEVICE8W iface)
     DeleteCriticalSection(&This->crit);
 
     free( This );
+}
+
+ULONG WINAPI IDirectInputDevice2WImpl_Release( IDirectInputDevice8W *iface )
+{
+    IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface );
+    ULONG ref = InterlockedDecrement( &impl->ref );
+
+    TRACE( "iface %p, ref %u.\n", iface, ref );
+
+    if (!ref)
+    {
+        if (impl->vtbl->release) impl->vtbl->release( iface );
+        else direct_input_device_destroy( iface );
+    }
 
     return ref;
 }
@@ -1132,11 +1142,11 @@ HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W ifa
     return E_NOINTERFACE;
 }
 
-ULONG WINAPI IDirectInputDevice2WImpl_AddRef(LPDIRECTINPUTDEVICE8W iface)
+ULONG WINAPI IDirectInputDevice2WImpl_AddRef( IDirectInputDevice8W *iface )
 {
-    IDirectInputDeviceImpl *This = impl_from_IDirectInputDevice8W(iface);
-    ULONG ref = InterlockedIncrement(&This->ref);
-    TRACE( "(%p) ref %d\n", This, ref );
+    IDirectInputDeviceImpl *impl = impl_from_IDirectInputDevice8W( iface );
+    ULONG ref = InterlockedIncrement( &impl->ref );
+    TRACE( "iface %p, ref %u.\n", iface, ref );
     return ref;
 }
 
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index d918403ef67..bdac5b4a378 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -57,6 +57,7 @@ typedef HRESULT dinput_device_read_state( IDirectInputDevice8W *iface );
 
 struct dinput_device_vtbl
 {
+    void (*release)( IDirectInputDevice8W *iface );
     HRESULT (*poll)( IDirectInputDevice8W *iface );
     HRESULT (*read)( IDirectInputDevice8W *iface );
     HRESULT (*acquire)( IDirectInputDevice8W *iface );
@@ -116,6 +117,7 @@ struct IDirectInputDeviceImpl
 extern HRESULT direct_input_device_alloc( SIZE_T size, const IDirectInputDevice8WVtbl *vtbl, const struct dinput_device_vtbl *internal_vtbl,
                                           const GUID *guid, IDirectInputImpl *dinput, void **out ) DECLSPEC_HIDDEN;
 extern HRESULT direct_input_device_init( IDirectInputDevice8W *iface );
+extern void direct_input_device_destroy( IDirectInputDevice8W *iface );
 extern const IDirectInputDevice8AVtbl dinput_device_a_vtbl DECLSPEC_HIDDEN;
 
 extern BOOL get_app_key(HKEY*, HKEY*) DECLSPEC_HIDDEN;
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index 90c60209192..766e022ebe0 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -158,7 +158,7 @@ struct pid_set_ramp_force
 struct hid_joystick
 {
     IDirectInputDeviceImpl base;
-    LONG ref;
+    LONG internal_ref;
 
     HANDLE device;
     OVERLAPPED read_ovl;
@@ -608,45 +608,30 @@ static BOOL enum_objects( struct hid_joystick *impl, const DIPROPHEADER *filter,
     return DIENUM_CONTINUE;
 }
 
-static ULONG hid_joystick_private_incref( struct hid_joystick *impl )
+static void hid_joystick_internal_addref( IDirectInputDevice8W *iface )
 {
-    return IDirectInputDevice2WImpl_AddRef( &impl->base.IDirectInputDevice8W_iface );
+    struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
+    ULONG ref = InterlockedIncrement( &impl->internal_ref );
+    TRACE( "iface %p, internal ref %u.\n", iface, ref );
 }
 
-static ULONG hid_joystick_private_decref( struct hid_joystick *impl )
+static void hid_joystick_internal_release( IDirectInputDevice8W *iface )
 {
-    struct hid_joystick tmp = *impl;
-    ULONG ref;
+    struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
+    ULONG ref = InterlockedDecrement( &impl->internal_ref );
+    TRACE( "iface %p, internal ref %u.\n", iface, ref );
 
-    if (!(ref = IDirectInputDevice2WImpl_Release( &impl->base.IDirectInputDevice8W_iface )))
+    if (!ref)
     {
-        free( tmp.usages_buf );
-        free( tmp.output_report_buf );
-        free( tmp.input_report_buf );
-        free( tmp.input_extra_caps );
-        HidD_FreePreparsedData( tmp.preparsed );
-        CloseHandle( tmp.base.read_event );
-        CloseHandle( tmp.device );
+        free( impl->usages_buf );
+        free( impl->output_report_buf );
+        free( impl->input_report_buf );
+        free( impl->input_extra_caps );
+        HidD_FreePreparsedData( impl->preparsed );
+        CloseHandle( impl->base.read_event );
+        CloseHandle( impl->device );
+        direct_input_device_destroy( iface );
     }
-
-    return ref;
-}
-
-static ULONG WINAPI hid_joystick_AddRef( IDirectInputDevice8W *iface )
-{
-    struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
-    ULONG ref = InterlockedIncrement( &impl->ref );
-    TRACE( "iface %p, ref %u.\n", iface, ref );
-    return ref;
-}
-
-static ULONG WINAPI hid_joystick_Release( IDirectInputDevice8W *iface )
-{
-    struct hid_joystick *impl = impl_from_IDirectInputDevice8W( iface );
-    ULONG ref = InterlockedDecrement( &impl->ref );
-    TRACE( "iface %p, ref %u.\n", iface, ref );
-    if (!ref) hid_joystick_private_decref( impl );
-    return ref;
 }
 
 static HRESULT hid_joystick_internal_get_property( IDirectInputDevice8W *iface, DWORD property, DIPROPHEADER *header,
@@ -1150,8 +1135,8 @@ static const IDirectInputDevice8WVtbl hid_joystick_vtbl =
 {
     /*** IUnknown methods ***/
     IDirectInputDevice2WImpl_QueryInterface,
-    hid_joystick_AddRef,
-    hid_joystick_Release,
+    IDirectInputDevice2WImpl_AddRef,
+    IDirectInputDevice2WImpl_Release,
     /*** IDirectInputDevice methods ***/
     IDirectInputDevice2WImpl_GetCapabilities,
     IDirectInputDevice2WImpl_EnumObjects,
@@ -1404,6 +1389,7 @@ static HRESULT hid_joystick_internal_enum_objects( IDirectInputDevice8W *iface,
 
 static const struct dinput_device_vtbl hid_joystick_internal_vtbl =
 {
+    hid_joystick_internal_release,
     NULL,
     hid_joystick_internal_read,
     hid_joystick_internal_acquire,
@@ -1979,7 +1965,7 @@ static HRESULT hid_joystick_create_device( IDirectInputImpl *dinput, const GUID
                                    &attrs, &impl->caps, dinput->dwVersion );
     if (hr != DI_OK) goto failed;
 
-    impl->ref = 1;
+    impl->internal_ref = 1;
     impl->base.instance = instance;
     impl->base.caps.dwDevType = instance.dwDevType;
     impl->attrs = attrs;
@@ -2097,7 +2083,7 @@ static ULONG WINAPI hid_joystick_effect_Release( IDirectInputEffect *iface )
         EnterCriticalSection( &impl->joystick->base.crit );
         list_remove( &impl->entry );
         LeaveCriticalSection( &impl->joystick->base.crit );
-        hid_joystick_private_decref( impl->joystick );
+        hid_joystick_internal_release( &impl->joystick->base.IDirectInputDevice8W_iface );
         free( impl->type_specific_buf[1] );
         free( impl->type_specific_buf[0] );
         free( impl->effect_update_buf );
@@ -2934,7 +2920,7 @@ static HRESULT hid_joystick_effect_create( struct hid_joystick *joystick, IDirec
     impl->IDirectInputEffect_iface.lpVtbl = &hid_joystick_effect_vtbl;
     impl->ref = 1;
     impl->joystick = joystick;
-    hid_joystick_private_incref( joystick );
+    hid_joystick_internal_addref( &joystick->base.IDirectInputDevice8W_iface );
 
     EnterCriticalSection( &joystick->base.crit );
     list_add_tail( &joystick->effect_list, &impl->entry );
diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index 75a2079f5fe..f17dc89ac16 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -330,6 +330,7 @@ static HRESULT keyboard_internal_set_property( IDirectInputDevice8W *iface, DWOR
 
 static const struct dinput_device_vtbl keyboard_internal_vtbl =
 {
+    NULL,
     keyboard_internal_poll,
     NULL,
     keyboard_internal_acquire,
diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c
index 69feb259d60..7fafa7696a7 100644
--- a/dlls/dinput/mouse.c
+++ b/dlls/dinput/mouse.c
@@ -643,6 +643,7 @@ static HRESULT mouse_internal_set_property( IDirectInputDevice8W *iface, DWORD p
 
 static const struct dinput_device_vtbl mouse_internal_vtbl =
 {
+    NULL,
     mouse_internal_poll,
     NULL,
     mouse_internal_acquire,




More information about the wine-cvs mailing list