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; }