Fix a crash when closing the main UI (#904)
* Fix a crash when closing the main Ui Also make sure to dispose the OpenAL context to not leak memory when unloading the emulation context. * Improve keys and 'game already running' dialogs * Make sure to dispose the page table and ThreadContext Less memory leaks! * Fix tests * Address gdk's comments
This commit is contained in:
parent
f2b9a9c2b0
commit
a906f2071c
7 changed files with 40 additions and 10 deletions
|
@ -101,6 +101,7 @@ namespace Ryujinx.Audio
|
||||||
}
|
}
|
||||||
|
|
||||||
_tracks.Clear();
|
_tracks.Clear();
|
||||||
|
_context.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -107,6 +107,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
public Keyset KeySet => Device.FileSystem.KeySet;
|
public Keyset KeySet => Device.FileSystem.KeySet;
|
||||||
|
|
||||||
private bool _hasStarted;
|
private bool _hasStarted;
|
||||||
|
private bool _isDisposed;
|
||||||
|
|
||||||
public BlitStruct<ApplicationControlProperty> ControlData { get; set; }
|
public BlitStruct<ApplicationControlProperty> ControlData { get; set; }
|
||||||
|
|
||||||
|
@ -740,8 +741,10 @@ namespace Ryujinx.HLE.HOS
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (!_isDisposed && disposing)
|
||||||
{
|
{
|
||||||
|
_isDisposed = true;
|
||||||
|
|
||||||
KProcess terminationProcess = new KProcess(this);
|
KProcess terminationProcess = new KProcess(this);
|
||||||
|
|
||||||
KThread terminationThread = new KThread(this);
|
KThread terminationThread = new KThread(this);
|
||||||
|
|
|
@ -1131,5 +1131,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||||
{
|
{
|
||||||
throw new UndefinedInstructionException(e.Address, e.OpCode);
|
throw new UndefinedInstructionException(e.Address, e.OpCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Destroy()
|
||||||
|
{
|
||||||
|
CpuMemory.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1141,6 +1141,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||||
{
|
{
|
||||||
Owner.Translator.Execute(Context, entrypoint);
|
Owner.Translator.Execute(Context, entrypoint);
|
||||||
|
|
||||||
|
Context.Dispose();
|
||||||
|
|
||||||
ThreadExit();
|
ThreadExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Ryujinx
|
||||||
string userProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch", "prod.keys");
|
string userProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch", "prod.keys");
|
||||||
if (!File.Exists(appDataPath) && !File.Exists(userProfilePath) && !Migration.IsMigrationNeeded())
|
if (!File.Exists(appDataPath) && !File.Exists(userProfilePath) && !Migration.IsMigrationNeeded())
|
||||||
{
|
{
|
||||||
GtkDialog.CreateErrorDialog("Key file was not found. Please refer to `KEYS.md` for more info");
|
GtkDialog.CreateWarningDialog("Key file was not found", "Please refer to `KEYS.md` for more info");
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow mainWindow = new MainWindow();
|
MainWindow mainWindow = new MainWindow();
|
||||||
|
|
|
@ -5,19 +5,29 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
internal class GtkDialog
|
internal class GtkDialog
|
||||||
{
|
{
|
||||||
internal static void CreateErrorDialog(string errorMessage)
|
internal static void CreateDialog(string title, string text, string secondaryText)
|
||||||
{
|
{
|
||||||
MessageDialog errorDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, null)
|
MessageDialog errorDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, null)
|
||||||
{
|
{
|
||||||
Title = "Ryujinx - Error",
|
Title = title,
|
||||||
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
||||||
Text = "Ryujinx has encountered an error",
|
Text = text,
|
||||||
SecondaryText = errorMessage,
|
SecondaryText = secondaryText,
|
||||||
WindowPosition = WindowPosition.Center
|
WindowPosition = WindowPosition.Center
|
||||||
};
|
};
|
||||||
errorDialog.SetSizeRequest(100, 20);
|
errorDialog.SetSizeRequest(100, 20);
|
||||||
errorDialog.Run();
|
errorDialog.Run();
|
||||||
errorDialog.Dispose();
|
errorDialog.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void CreateWarningDialog(string text, string secondaryText)
|
||||||
|
{
|
||||||
|
CreateDialog("Ryujinx - Warning", text, secondaryText);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void CreateErrorDialog(string errorMessage)
|
||||||
|
{
|
||||||
|
CreateDialog("Ryujinx - Error", "Ryujinx has encountered an error", errorMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private static GlScreen _screen;
|
private static GlScreen _screen;
|
||||||
|
|
||||||
|
private static AutoResetEvent _screenExitStatus = new AutoResetEvent(false);
|
||||||
|
|
||||||
private static ListStore _tableStore;
|
private static ListStore _tableStore;
|
||||||
|
|
||||||
private static bool _updatingGameTable;
|
private static bool _updatingGameTable;
|
||||||
|
@ -278,7 +280,7 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
if (_gameLoaded)
|
if (_gameLoaded)
|
||||||
{
|
{
|
||||||
GtkDialog.CreateErrorDialog("A game has already been loaded. Please close the emulator and try again");
|
GtkDialog.CreateDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -347,6 +349,8 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
_emulationContext = device;
|
_emulationContext = device;
|
||||||
|
|
||||||
|
_screenExitStatus.Reset();
|
||||||
|
|
||||||
#if MACOS_BUILD
|
#if MACOS_BUILD
|
||||||
CreateGameWindow(device);
|
CreateGameWindow(device);
|
||||||
#else
|
#else
|
||||||
|
@ -393,6 +397,8 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
DiscordIntegrationModule.SwitchToMainMenu();
|
DiscordIntegrationModule.SwitchToMainMenu();
|
||||||
|
|
||||||
|
_screenExitStatus.Set();
|
||||||
|
|
||||||
Application.Invoke(delegate
|
Application.Invoke(delegate
|
||||||
{
|
{
|
||||||
_stopEmulation.Sensitive = false;
|
_stopEmulation.Sensitive = false;
|
||||||
|
@ -432,12 +438,17 @@ namespace Ryujinx.Ui
|
||||||
if (device != null)
|
if (device != null)
|
||||||
{
|
{
|
||||||
UpdateGameMetadata(device.System.TitleIdText);
|
UpdateGameMetadata(device.System.TitleIdText);
|
||||||
|
|
||||||
|
if (_screen != null)
|
||||||
|
{
|
||||||
|
_screen.Exit();
|
||||||
|
_screenExitStatus.WaitOne();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispose();
|
Dispose();
|
||||||
|
|
||||||
Profile.FinishProfiling();
|
Profile.FinishProfiling();
|
||||||
device?.Dispose();
|
|
||||||
DiscordIntegrationModule.Exit();
|
DiscordIntegrationModule.Exit();
|
||||||
Logger.Shutdown();
|
Logger.Shutdown();
|
||||||
Application.Quit();
|
Application.Quit();
|
||||||
|
@ -584,13 +595,11 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private void Exit_Pressed(object sender, EventArgs args)
|
private void Exit_Pressed(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
_screen?.Exit();
|
|
||||||
End(_emulationContext);
|
End(_emulationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Close(object sender, DeleteEventArgs args)
|
private void Window_Close(object sender, DeleteEventArgs args)
|
||||||
{
|
{
|
||||||
_screen?.Exit();
|
|
||||||
End(_emulationContext);
|
End(_emulationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue