From a27986c31167d8ce60efcee7e901da241f63ed08 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 4 Aug 2021 15:28:33 -0300 Subject: Make audio disposal thread safe on all 3 backends (#2527) * Make audio disposal thread safe on all 3 backends * Make OpenAL more consistent with the other backends * Remove Window.Cursor = null, and change dummy TValue to byte --- .../SoundIoHardwareDeviceDriver.cs | 50 ++++++---------------- .../SoundIoHardwareDeviceSession.cs | 4 +- 2 files changed, 14 insertions(+), 40 deletions(-) (limited to 'Ryujinx.Audio.Backends.SoundIo') diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs index b9b549e6..20aa4cbf 100644 --- a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs +++ b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs @@ -3,7 +3,7 @@ using Ryujinx.Audio.Integration; using Ryujinx.Memory; using SoundIOSharp; using System; -using System.Collections.Generic; +using System.Collections.Concurrent; using System.Threading; using static Ryujinx.Audio.Integration.IHardwareDeviceDriver; @@ -12,19 +12,17 @@ namespace Ryujinx.Audio.Backends.SoundIo { public class SoundIoHardwareDeviceDriver : IHardwareDeviceDriver { - private object _lock = new object(); - - private SoundIO _audioContext; - private SoundIODevice _audioDevice; - private ManualResetEvent _updateRequiredEvent; - private List _sessions; + private readonly SoundIO _audioContext; + private readonly SoundIODevice _audioDevice; + private readonly ManualResetEvent _updateRequiredEvent; + private readonly ConcurrentDictionary _sessions; private int _disposeState; public SoundIoHardwareDeviceDriver() { _audioContext = new SoundIO(); _updateRequiredEvent = new ManualResetEvent(false); - _sessions = new List(); + _sessions = new ConcurrentDictionary(); _audioContext.Connect(); _audioContext.FlushEvents(); @@ -142,22 +140,16 @@ namespace Ryujinx.Audio.Backends.SoundIo throw new NotImplementedException("Input direction is currently not implemented on SoundIO backend!"); } - lock (_lock) - { - SoundIoHardwareDeviceSession session = new SoundIoHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount); + SoundIoHardwareDeviceSession session = new SoundIoHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount); - _sessions.Add(session); + _sessions.TryAdd(session, 0); - return session; - } + return session; } - internal void Unregister(SoundIoHardwareDeviceSession session) + internal bool Unregister(SoundIoHardwareDeviceSession session) { - lock (_lock) - { - _sessions.Remove(session); - } + return _sessions.TryRemove(session, out _); } public static SoundIOFormat GetSoundIoFormat(SampleFormat format) @@ -219,26 +211,10 @@ namespace Ryujinx.Audio.Backends.SoundIo { if (disposing) { - int sessionCount = 0; - - // NOTE: This is done in a way to avoid possible situations when the SoundIoHardwareDeviceSession is already being dispose in another thread but doesn't hold the lock and tries to Unregister. - do + foreach (SoundIoHardwareDeviceSession session in _sessions.Keys) { - lock (_lock) - { - if (_sessions.Count == 0) - { - break; - } - - SoundIoHardwareDeviceSession session = _sessions[_sessions.Count - 1]; - - session.Dispose(); - - sessionCount = _sessions.Count; - } + session.Dispose(); } - while (sessionCount > 0); _audioContext.Disconnect(); _audioContext.Dispose(); diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs index 884e75ed..ee2eeb77 100644 --- a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs +++ b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs @@ -423,14 +423,12 @@ namespace Ryujinx.Audio.Backends.SoundIo protected virtual void Dispose(bool disposing) { - if (disposing) + if (disposing && _driver.Unregister(this)) { PrepareToClose(); Stop(); _outputStream.Dispose(); - - _driver.Unregister(this); } } -- cgit v1.2.3