Giovanni Mascellani (@giomasce) commented about dlls/mfplat/main.c:
+ DeleteCriticalSection(&syncobj->cs); + free(syncobj); + } + + return refcount; +} + +static HRESULT WINAPI d3d12_sync_object_SignalEventOnFinalResourceRelease(IMFD3D12SynchronizationObject *iface, HANDLE event) +{ + struct d3d12_sync_object *syncobj = impl_from_IMFD3D12SynchronizationObject(iface); + + TRACE("%p, %p.\n", iface, event); + + EnterCriticalSection(&syncobj->cs); + if (syncobj->release_wait) + syncobj->final_release_event = event; You treat `final_release_event` as a borrowed reference, i.e. assuming that the caller won't destroy the handle it passed here until everything is done. This might or might not be correct, and it doesn't seem that tests are testing this. The caller might immediately destroy the handle and then wait for the event through a different duplicated handle, in which case you'd need to make your own duplicate here.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9777#note_137214