|
|
@@ -3,7 +3,7 @@ using Ryujinx.Audio.Common;
|
|
|
using Ryujinx.Audio.Integration;
|
|
|
using Ryujinx.Memory;
|
|
|
using System;
|
|
|
-using System.Collections.Generic;
|
|
|
+using System.Collections.Concurrent;
|
|
|
using System.Linq;
|
|
|
using System.Threading;
|
|
|
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
|
|
|
@@ -12,11 +12,10 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|
|
{
|
|
|
public class OpenALHardwareDeviceDriver : IHardwareDeviceDriver
|
|
|
{
|
|
|
- private object _lock = new object();
|
|
|
- private ALDevice _device;
|
|
|
- private ALContext _context;
|
|
|
- private ManualResetEvent _updateRequiredEvent;
|
|
|
- private List<OpenALHardwareDeviceSession> _sessions;
|
|
|
+ private readonly ALDevice _device;
|
|
|
+ private readonly ALContext _context;
|
|
|
+ private readonly ManualResetEvent _updateRequiredEvent;
|
|
|
+ private readonly ConcurrentDictionary<OpenALHardwareDeviceSession, byte> _sessions;
|
|
|
private bool _stillRunning;
|
|
|
private Thread _updaterThread;
|
|
|
|
|
|
@@ -25,7 +24,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|
|
_device = ALC.OpenDevice("");
|
|
|
_context = ALC.CreateContext(_device, new ALContextAttributes());
|
|
|
_updateRequiredEvent = new ManualResetEvent(false);
|
|
|
- _sessions = new List<OpenALHardwareDeviceSession>();
|
|
|
+ _sessions = new ConcurrentDictionary<OpenALHardwareDeviceSession, byte>();
|
|
|
|
|
|
_stillRunning = true;
|
|
|
_updaterThread = new Thread(Update)
|
|
|
@@ -72,22 +71,16 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|
|
throw new ArgumentException($"{channelCount}");
|
|
|
}
|
|
|
|
|
|
- lock (_lock)
|
|
|
- {
|
|
|
- OpenALHardwareDeviceSession session = new OpenALHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount);
|
|
|
+ OpenALHardwareDeviceSession session = new OpenALHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount);
|
|
|
|
|
|
- _sessions.Add(session);
|
|
|
+ _sessions.TryAdd(session, 0);
|
|
|
|
|
|
- return session;
|
|
|
- }
|
|
|
+ return session;
|
|
|
}
|
|
|
|
|
|
- internal void Unregister(OpenALHardwareDeviceSession session)
|
|
|
+ internal bool Unregister(OpenALHardwareDeviceSession session)
|
|
|
{
|
|
|
- lock (_lock)
|
|
|
- {
|
|
|
- _sessions.Remove(session);
|
|
|
- }
|
|
|
+ return _sessions.TryRemove(session, out _);
|
|
|
}
|
|
|
|
|
|
public ManualResetEvent GetUpdateRequiredEvent()
|
|
|
@@ -103,14 +96,11 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|
|
{
|
|
|
bool updateRequired = false;
|
|
|
|
|
|
- lock (_lock)
|
|
|
+ foreach (OpenALHardwareDeviceSession session in _sessions.Keys)
|
|
|
{
|
|
|
- foreach (OpenALHardwareDeviceSession session in _sessions)
|
|
|
+ if (session.Update())
|
|
|
{
|
|
|
- if (session.Update())
|
|
|
- {
|
|
|
- updateRequired = true;
|
|
|
- }
|
|
|
+ updateRequired = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -135,26 +125,10 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|
|
{
|
|
|
_stillRunning = false;
|
|
|
|
|
|
- int sessionCount = 0;
|
|
|
-
|
|
|
- // NOTE: This is done in a way to avoid possible situations when the OpenALHardwareDeviceSession is already being dispose in another thread but doesn't hold the lock and tries to Unregister.
|
|
|
- do
|
|
|
+ foreach (OpenALHardwareDeviceSession session in _sessions.Keys)
|
|
|
{
|
|
|
- lock (_lock)
|
|
|
- {
|
|
|
- if (_sessions.Count == 0)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- OpenALHardwareDeviceSession session = _sessions[_sessions.Count - 1];
|
|
|
-
|
|
|
- session.Dispose();
|
|
|
-
|
|
|
- sessionCount = _sessions.Count;
|
|
|
- }
|
|
|
+ session.Dispose();
|
|
|
}
|
|
|
- while (sessionCount > 0);
|
|
|
|
|
|
ALC.DestroyContext(_context);
|
|
|
ALC.CloseDevice(_device);
|