diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs index 53570243d..1ad7b8590 100644 --- a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs +++ b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs @@ -31,7 +31,6 @@ namespace Ryujinx.Audio.Renderer.Server private AudioRendererRenderingDevice _renderingDevice; private AudioRendererExecutionMode _executionMode; private IWritableEvent _systemEvent; - private ManualResetEvent _terminationEvent; private MemoryPoolState _dspMemoryPoolState; private VoiceContext _voiceContext; private MixContext _mixContext; @@ -83,7 +82,6 @@ namespace Ryujinx.Audio.Renderer.Server public AudioRenderSystem(AudioRendererManager manager, IWritableEvent systemEvent) { _manager = manager; - _terminationEvent = new ManualResetEvent(false); _dspMemoryPoolState = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp); _voiceContext = new VoiceContext(); _mixContext = new MixContext(); @@ -387,11 +385,6 @@ namespace Ryujinx.Audio.Renderer.Server _isActive = false; } - if (_executionMode == AudioRendererExecutionMode.Auto) - { - _terminationEvent.WaitOne(); - } - Logger.Info?.Print(LogClass.AudioRenderer, $"Stopped renderer id {_sessionId}"); } @@ -668,8 +661,6 @@ namespace Ryujinx.Audio.Renderer.Server { if (_isActive) { - _terminationEvent.Reset(); - if (!_manager.Processor.HasRemainingCommands(_sessionId)) { GenerateCommandList(out CommandList commands); @@ -686,10 +677,6 @@ namespace Ryujinx.Audio.Renderer.Server _isDspRunningBehind = true; } } - else - { - _terminationEvent.Set(); - } } } @@ -857,7 +844,6 @@ namespace Ryujinx.Audio.Renderer.Server } _manager.Unregister(this); - _terminationEvent.Dispose(); _workBufferMemoryPin.Dispose(); if (MemoryManager is IRefCounted rc) diff --git a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs b/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs index 7e2afb8bd..f207c5fb0 100644 --- a/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs +++ b/src/Ryujinx.Ava/UI/Helpers/NotificationHelper.cs @@ -3,21 +3,20 @@ using Avalonia.Controls; using Avalonia.Controls.Notifications; using Avalonia.Threading; using Ryujinx.Ava.Common.Locale; +using Ryujinx.Common; using System; using System.Collections.Concurrent; using System.Threading; -using System.Threading.Tasks; namespace Ryujinx.Ava.UI.Helpers { public static class NotificationHelper { - private const int MaxNotifications = 4; + private const int MaxNotifications = 4; private const int NotificationDelayInMs = 5000; private static WindowNotificationManager _notificationManager; - private static readonly ManualResetEvent _templateAppliedEvent = new(false); private static readonly BlockingCollection _notifications = new(); public static void SetNotificationManager(Window host) @@ -29,25 +28,31 @@ namespace Ryujinx.Ava.UI.Helpers Margin = new Thickness(0, 0, 15, 40) }; + var maybeAsyncWorkQueue = new Lazy>( + () => new AsyncWorkQueue(notification => + { + Dispatcher.UIThread.Post(() => + { + _notificationManager.Show(notification); + }); + }, + "UI.NotificationThread", + _notifications), + LazyThreadSafetyMode.ExecutionAndPublication); + _notificationManager.TemplateApplied += (sender, args) => { - _templateAppliedEvent.Set(); + // NOTE: Force creation of the AsyncWorkQueue. + _ = maybeAsyncWorkQueue.Value; }; - Task.Run(async () => + host.Closing += (sender, args) => { - _templateAppliedEvent.WaitOne(); - - foreach (var notification in _notifications.GetConsumingEnumerable()) + if (maybeAsyncWorkQueue.IsValueCreated) { - Dispatcher.UIThread.Post(() => - { - _notificationManager.Show(notification); - }); - - await Task.Delay(NotificationDelayInMs / MaxNotifications); + maybeAsyncWorkQueue.Value.Dispose(); } - }); + }; } public static void Show(string title, string text, NotificationType type, bool waitingExit = false, Action onClick = null, Action onClose = null) diff --git a/src/Ryujinx.Common/AsyncWorkQueue.cs b/src/Ryujinx.Common/AsyncWorkQueue.cs index 80f8dcfe4..746ef4cac 100644 --- a/src/Ryujinx.Common/AsyncWorkQueue.cs +++ b/src/Ryujinx.Common/AsyncWorkQueue.cs @@ -22,9 +22,11 @@ namespace Ryujinx.Common _cts = new CancellationTokenSource(); _queue = collection; _workerAction = callback; - _workerThread = new Thread(DoWork) { Name = name }; - - _workerThread.IsBackground = true; + _workerThread = new Thread(DoWork) + { + Name = name, + IsBackground = true + }; _workerThread.Start(); }