I don't think this works if RtwqInvokeCallback() fails. The point of checking first and decrementing later is because of a circular reference between tracked_result and the sample. In normal case after SetAllocator() you get refcount == 2 and tracked_refcount == 1. Now it queues are not working: * Release() decrements to refcount == 1 and tracked_refcount == 1; * condition matches and tracked result it released, recursing back to sample_tracked_Release(); * recursed call decrements refcount to 0 and releases the sample. So you're losing 2 references on a single Release() call. I supposed decrementing while still locked will work? P.S. note that there is almost identical copy of this in dlls/evr/sample.c that needs the same fix, and probably use of an explicit enter/leave instead of a LockStore(). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/29#note_567