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.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Processes;
using Ryujinx.Input;
using Ryujinx.Input.HLE;
using Ryujinx.Ui.Common;
@ -427,9 +428,12 @@ namespace Ryujinx.Ava
_isActive = false;
if (_renderingStarted)
{
// 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();
DisplaySleep.Restore();
@ -445,7 +449,7 @@ namespace Ryujinx.Ava
private void Dispose()
{
if (Device.Processes != null)
if (!ProcessResult.Failed.Equals(Device?.Processes?.ActiveApplication))
{
_viewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText);
}

View file

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

View file

@ -24,7 +24,15 @@ namespace Ryujinx.HLE.Loaders.Processes
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)
{

View file

@ -6,12 +6,14 @@ using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.Horizon.Common;
using System;
using System.Linq;
namespace Ryujinx.HLE.Loaders.Processes
{
public class ProcessResult
{
public static ProcessResult Failed => new(null, new BlitStruct<ApplicationControlProperty>(1), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish);
private readonly byte _mainThreadPriority;
@ -91,5 +93,46 @@ namespace Ryujinx.HLE.Loaders.Processes
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();
}
}
}