diff options
Diffstat (limited to 'Ryujinx.Memory/Tracking/RegionHandle.cs')
-rw-r--r-- | Ryujinx.Memory/Tracking/RegionHandle.cs | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs index 2e45ef80..2df02f1e 100644 --- a/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -1,6 +1,7 @@ using Ryujinx.Memory.Range; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; namespace Ryujinx.Memory.Tracking @@ -112,7 +113,7 @@ namespace Ryujinx.Memory.Tracking /// Signal that a memory action occurred within this handle's virtual regions. /// </summary> /// <param name="write">Whether the region was written to or read</param> - internal void Signal(ulong address, ulong size, bool write) + internal void Signal(ulong address, ulong size, bool write, ref IList<RegionHandle> handleIterable) { RegionSignal action = Interlocked.Exchange(ref _preAction, null); @@ -124,7 +125,26 @@ namespace Ryujinx.Memory.Tracking return; } - action?.Invoke(address, size); + if (action != null) + { + // Copy the handles list in case it changes when we're out of the lock. + if (handleIterable is List<RegionHandle>) + { + handleIterable = handleIterable.ToArray(); + } + + // Temporarily release the tracking lock while we're running the action. + Monitor.Exit(_tracking.TrackingLock); + + try + { + action.Invoke(address, size); + } + finally + { + Monitor.Enter(_tracking.TrackingLock); + } + } if (write) { |