MR29v1 - mfplat: Avoid a race condition when releasing a tracked sample.

Giovanni Mascellani (@giomasce) wine at gitlab.winehq.org
Wed May 4 03:13:41 CDT 2022


I might be missing something, but isn't that what is supposed to happen? If `RtwqInvokeCallback()` fails (and `tracked_result` is then released), then nobody will ever pick the sample up again, so it is appropriate to have it freed, isn't it?

As you say, after `SetAllocator()` is called `refcount == 2` (one reference is the client, the other is the object self-reference itself) and `tracked_refcount == 1` (the self-reference again). Once the client code is done, it calls `Release()` and `refcount` drops to 1, so the callback is called.

* If the callback succeeds, presumably the client (specifically, the sample allocator, I believe) code will take a reference to the sample again, so `refcount` will become 2 again. After the async result is released and presumably freed, it will release the self-reference to the sample, so `refcount` will go to 1 again. And of course `tracked_refcount` is set to zero. This seems to be correct: at the end of the process there is precisely a reference to the sample, by the sample allocator.

* If the callback fails, the client will never recover a reference to the sample, so `refcount` will remain at 1, just to drop to zero once the async result is freed. This is correct: nobody holds a reference to the sample any more, and then it's correct to free it.

So I don't understand what is the problem that you're seeing.

-- 
https://gitlab.winehq.org/wine/wine/-/merge_requests/29#note_588



More information about the wine-devel mailing list