Fix flush action from multiple threads regression (#3311)

If two or more threads encounter a region of memory where a read action has been registered, then they must _both_ wait on the data.

Clearing the action before it completed was causing the null check above to fail, so the action would only be run on the first thread, and the second would end up continuing without waiting. Depending on what the game does, this could be disasterous.

This fixes a regression introduced by #3302 with Pokemon Legends Arceus, and possibly Catherine. There are likely other affected games. What is fixed in that PR should still be fixed.
This commit is contained in:
riperiperi 2022-05-02 11:31:53 +01:00 committed by GitHub
parent 9eb5b7a10d
commit 4a892fbdc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -144,9 +144,11 @@ namespace Ryujinx.Memory.Tracking
{
lock (_preActionLock)
{
RegionSignal action = Interlocked.Exchange(ref _preAction, null);
_preAction?.Invoke(address, size);
action?.Invoke(address, size);
// The action is removed after it returns, to ensure that the null check above succeeds when
// it's still in progress rather than continuing and possibly missing a required data flush.
Interlocked.Exchange(ref _preAction, null);
}
}
finally