Make AppHost.Dispose more robust

This commit is contained in:
kekkon 2023-06-20 18:14:57 +02:00
parent 0ab80a9861
commit b1c62559cb
4 changed files with 60 additions and 8 deletions

View file

@ -30,6 +30,7 @@ using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.Input; using Ryujinx.Input;
using Ryujinx.Input.HLE; using Ryujinx.Input.HLE;
using Ryujinx.Ui.Common; using Ryujinx.Ui.Common;
@ -427,9 +428,12 @@ namespace Ryujinx.Ava
_isActive = false; _isActive = false;
// NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose. if (_renderingStarted)
// We only need to wait for all commands submitted during the main gpu loop to be processed. {
_gpuDoneEvent.WaitOne(); // NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
// We only need to wait for all commands submitted during the main gpu loop to be processed.
_gpuDoneEvent.WaitOne();
}
_gpuDoneEvent.Dispose(); _gpuDoneEvent.Dispose();
DisplaySleep.Restore(); DisplaySleep.Restore();
@ -445,7 +449,7 @@ namespace Ryujinx.Ava
private void Dispose() private void Dispose()
{ {
if (Device.Processes != null) if (!ProcessResult.Failed.Equals(Device?.Processes?.ActiveApplication))
{ {
_viewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText); _viewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText);
} }

View file

@ -1488,15 +1488,12 @@ namespace Ryujinx.Ava.UI.ViewModels
catch (HorizonResultException ex) catch (HorizonResultException ex)
{ {
// Apphost Cleanup // Apphost Cleanup
AppHost = null;
SelectedIcon = null; SelectedIcon = null;
await Dispatcher.UIThread.InvokeAsync(async () => await Dispatcher.UIThread.InvokeAsync(async () =>
{ {
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[LocaleKeys.DialogCorruptedGameError], ex.Message)); await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[LocaleKeys.DialogCorruptedGameError], ex.Message));
}); });
return;
} }
if (!isApplicationLoaded) if (!isApplicationLoaded)

View file

@ -24,7 +24,15 @@ namespace Ryujinx.HLE.Loaders.Processes
private ulong _latestPid; private ulong _latestPid;
public ProcessResult ActiveApplication => _processesByPid[_latestPid]; public ProcessResult ActiveApplication
{
get
{
return _processesByPid.TryGetValue(_latestPid, out ProcessResult processResult)
? processResult
: ProcessResult.Failed;
}
}
public ProcessLoader(Switch device) public ProcessLoader(Switch device)
{ {

View file

@ -6,12 +6,14 @@ using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Common;
using System;
using System.Linq; using System.Linq;
namespace Ryujinx.HLE.Loaders.Processes namespace Ryujinx.HLE.Loaders.Processes
{ {
public class ProcessResult public class ProcessResult
{ {
public static ProcessResult Failed => new(null, new BlitStruct<ApplicationControlProperty>(1), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish); public static ProcessResult Failed => new(null, new BlitStruct<ApplicationControlProperty>(1), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish);
private readonly byte _mainThreadPriority; private readonly byte _mainThreadPriority;
@ -91,5 +93,46 @@ namespace Ryujinx.HLE.Loaders.Processes
return true; return true;
} }
protected bool Equals(ProcessResult other)
{
return _mainThreadPriority == other._mainThreadPriority && _mainThreadStackSize == other._mainThreadStackSize && ProcessId == other.ProcessId && Name == other.Name && DisplayVersion == other.DisplayVersion && ProgramId == other.ProgramId && ProgramIdText == other.ProgramIdText && Is64Bit == other.Is64Bit && DiskCacheEnabled == other.DiskCacheEnabled && AllowCodeMemoryForJit == other.AllowCodeMemoryForJit;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != this.GetType())
{
return false;
}
return Equals((ProcessResult)obj);
}
public override int GetHashCode()
{
HashCode hashCode = new HashCode();
hashCode.Add(_mainThreadPriority);
hashCode.Add(_mainThreadStackSize);
hashCode.Add(ProcessId);
hashCode.Add(Name);
hashCode.Add(DisplayVersion);
hashCode.Add(ProgramId);
hashCode.Add(ProgramIdText);
hashCode.Add(Is64Bit);
hashCode.Add(DiskCacheEnabled);
hashCode.Add(AllowCodeMemoryForJit);
return hashCode.ToHashCode();
}
} }
} }