From 4a892fbdc9059504358ddf41c27576032e1ce414 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Mon, 2 May 2022 11:31:53 +0100 Subject: [PATCH] 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. --- Ryujinx.Memory/Tracking/RegionHandle.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs index b30dcbc254..14c6de2c95 100644 --- a/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -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