From: Rémi Bernon rbernon@codeweavers.com
--- dlls/windows.gaming.input/event_handlers.c | 40 ++++++++++++++++------ 1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/dlls/windows.gaming.input/event_handlers.c b/dlls/windows.gaming.input/event_handlers.c index b9b061e3362..b63ffffa014 100644 --- a/dlls/windows.gaming.input/event_handlers.c +++ b/dlls/windows.gaming.input/event_handlers.c @@ -36,12 +36,26 @@ struct handler_entry IEventHandler_IInspectable *handler; };
+static struct handler_entry *handler_entry_create( IEventHandler_IInspectable *handler ) +{ + struct handler_entry *entry; + if (!(entry = calloc( 1, sizeof(*entry) ))) return NULL; + IEventHandler_IInspectable_AddRef( (entry->handler = handler) ); + + return entry; +} + +static void handler_entry_destroy( struct handler_entry *entry ) +{ + IEventHandler_IInspectable_Release( entry->handler ); + free( entry ); +} + HRESULT event_handlers_append( struct list *list, IEventHandler_IInspectable *handler, EventRegistrationToken *token ) { struct handler_entry *entry;
- if (!(entry = calloc( 1, sizeof(*entry) ))) return E_OUTOFMEMORY; - IEventHandler_IInspectable_AddRef( (entry->handler = handler) ); + if (!(entry = handler_entry_create( handler ))) return E_OUTOFMEMORY;
EnterCriticalSection( &handlers_cs );
@@ -67,23 +81,29 @@ HRESULT event_handlers_remove( struct list *list, EventRegistrationToken *token
LeaveCriticalSection( &handlers_cs );
- if (found) - { - IEventHandler_IInspectable_Release( entry->handler ); - free( entry ); - } - + if (found) handler_entry_destroy( entry ); return S_OK; }
void event_handlers_notify( struct list *list, IInspectable *element ) { - struct handler_entry *entry; + struct handler_entry *entry, *next, *copy; + struct list copies = LIST_INIT(copies);
EnterCriticalSection( &handlers_cs );
LIST_FOR_EACH_ENTRY( entry, list, struct handler_entry, entry ) - IEventHandler_IInspectable_Invoke( entry->handler, NULL, element ); + { + if (!(copy = handler_entry_create( entry->handler ))) continue; + list_add_tail( &copies, ©->entry ); + }
LeaveCriticalSection( &handlers_cs ); + + LIST_FOR_EACH_ENTRY_SAFE( entry, next, &copies, struct handler_entry, entry ) + { + IEventHandler_IInspectable_Invoke( entry->handler, NULL, element ); + list_remove( &entry->entry ); + handler_entry_destroy( entry ); + } }
From: Rémi Bernon rbernon@codeweavers.com
--- .../event_handlers.c | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.devices.enumeration/event_handlers.c b/dlls/windows.devices.enumeration/event_handlers.c index 4989a983e55..6f56a32a58e 100644 --- a/dlls/windows.devices.enumeration/event_handlers.c +++ b/dlls/windows.devices.enumeration/event_handlers.c @@ -36,6 +36,20 @@ struct typed_event_handler_entry ITypedEventHandler_IInspectable_IInspectable *handler; };
+static struct typed_event_handler_entry *typed_event_handler_entry_create( ITypedEventHandler_IInspectable_IInspectable *handler ) +{ + struct typed_event_handler_entry *entry; + if (!(entry = calloc( 1, sizeof(*entry) ))) return NULL; + ITypedEventHandler_IInspectable_IInspectable_AddRef( (entry->handler = handler) ); + return entry; +} + +static void typed_event_handler_entry_destroy( struct typed_event_handler_entry *entry ) +{ + ITypedEventHandler_IInspectable_IInspectable_Release( entry->handler ); + free( entry ); +} + HRESULT typed_event_handlers_append( struct list *list, ITypedEventHandler_IInspectable_IInspectable *handler, EventRegistrationToken *token ) { struct typed_event_handler_entry *entry; @@ -78,15 +92,26 @@ HRESULT typed_event_handlers_remove( struct list *list, EventRegistrationToken *
HRESULT typed_event_handlers_notify( struct list *list, IInspectable *sender, IInspectable *args ) { - struct typed_event_handler_entry *entry; + struct typed_event_handler_entry *entry, *next, *copy; + struct list copies = LIST_INIT(copies);
EnterCriticalSection( &handlers_cs );
LIST_FOR_EACH_ENTRY( entry, list, struct typed_event_handler_entry, entry ) - ITypedEventHandler_IInspectable_IInspectable_Invoke( entry->handler, sender, args ); + { + if (!(copy = typed_event_handler_entry_create( entry->handler ))) continue; + list_add_tail( &copies, ©->entry ); + }
LeaveCriticalSection( &handlers_cs );
+ LIST_FOR_EACH_ENTRY_SAFE( entry, next, &copies, struct typed_event_handler_entry, entry ) + { + ITypedEventHandler_IInspectable_IInspectable_Invoke( entry->handler, sender, args ); + list_remove( &entry->entry ); + typed_event_handler_entry_destroy( entry ); + } + return S_OK; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/windows.media.speech/event_handlers.c | 29 ++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/dlls/windows.media.speech/event_handlers.c b/dlls/windows.media.speech/event_handlers.c index 7b5db971d1a..14a1be22c0a 100644 --- a/dlls/windows.media.speech/event_handlers.c +++ b/dlls/windows.media.speech/event_handlers.c @@ -36,6 +36,20 @@ struct typed_event_handler_entry ITypedEventHandler_IInspectable_IInspectable *handler; };
+static struct typed_event_handler_entry *typed_event_handler_entry_create(ITypedEventHandler_IInspectable_IInspectable *handler) +{ + struct typed_event_handler_entry *entry; + if (!(entry = calloc(1, sizeof(*entry)))) return NULL; + ITypedEventHandler_IInspectable_IInspectable_AddRef((entry->handler = handler)); + return entry; +} + +static void typed_event_handler_entry_destroy(struct typed_event_handler_entry *entry) +{ + ITypedEventHandler_IInspectable_IInspectable_Release(entry->handler); + free(entry); +} + HRESULT typed_event_handlers_append( struct list *list, ITypedEventHandler_IInspectable_IInspectable *handler, EventRegistrationToken *token ) { struct typed_event_handler_entry *entry; @@ -78,15 +92,26 @@ HRESULT typed_event_handlers_remove( struct list *list, EventRegistrationToken *
HRESULT typed_event_handlers_notify( struct list *list, IInspectable *sender, IInspectable *args ) { - struct typed_event_handler_entry *entry; + struct typed_event_handler_entry *entry, *next, *copy; + struct list copies = LIST_INIT(copies);
EnterCriticalSection(&handlers_cs);
LIST_FOR_EACH_ENTRY(entry, list, struct typed_event_handler_entry, entry) - ITypedEventHandler_IInspectable_IInspectable_Invoke(entry->handler, sender, args); + { + if (!(copy = typed_event_handler_entry_create( entry->handler ))) continue; + list_add_tail( &copies, ©->entry ); + }
LeaveCriticalSection(&handlers_cs);
+ LIST_FOR_EACH_ENTRY_SAFE(entry, next, &copies, struct typed_event_handler_entry, entry) + { + ITypedEventHandler_IInspectable_IInspectable_Invoke(entry->handler, sender, args); + list_remove(&entry->entry); + typed_event_handler_entry_destroy(entry); + } + return S_OK; }
Did you encounter some deadlock in this library? And is there a bug report for it?
Astral Ascent deadlocks and no, there's no bug report for it.