Inline PlatformSpecificMainLoopCrashHandler and implentations
UnixMono copy contained workaround for a bug that has since been fixed
This commit is contained in:
parent
e8f66570ad
commit
2d5b069793
|
@ -89,121 +89,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
return SubMain(args);
|
||||
}
|
||||
|
||||
private interface PlatformSpecificMainLoopCrashHandler
|
||||
{
|
||||
void TryCatchFinally(string[] args);
|
||||
}
|
||||
private class Win32MainLoopCrashHandler : PlatformSpecificMainLoopCrashHandler
|
||||
{
|
||||
public void TryCatchFinally(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Global.Config.SingleInstanceMode)
|
||||
{
|
||||
try
|
||||
{
|
||||
new SingleInstanceController(args).Run(args);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Eat it, MainForm disposed itself and Run attempts to dispose of itself. Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var mf = new MainForm(args))
|
||||
{
|
||||
var title = mf.Text;
|
||||
mf.Show();
|
||||
mf.Text = title;
|
||||
try
|
||||
{
|
||||
GlobalWin.ExitCode = mf.ProgramRunLoop();
|
||||
}
|
||||
catch (Exception e) when (!Debugger.IsAttached && !VersionInfo.DeveloperBuild && Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
var result = MessageBox.Show(
|
||||
"EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)",
|
||||
$"Fatal error: {e.GetType().Name}",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Exclamation
|
||||
);
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
Global.MovieSession.Movie.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (!Debugger.IsAttached)
|
||||
{
|
||||
new ExceptionBox(e).ShowDialog();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (GlobalWin.Sound != null)
|
||||
{
|
||||
GlobalWin.Sound.Dispose();
|
||||
GlobalWin.Sound = null;
|
||||
}
|
||||
GlobalWin.GL.Dispose();
|
||||
Input.Cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
private class UnixMonoMainLoopCrashHandler : PlatformSpecificMainLoopCrashHandler
|
||||
{
|
||||
// Identical to the implementation in Win32MainLoopCrashHandler sans the single-instance check.
|
||||
public void TryCatchFinally(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var mf = new MainForm(args))
|
||||
{
|
||||
var title = mf.Text;
|
||||
mf.Show();
|
||||
mf.Text = title;
|
||||
try
|
||||
{
|
||||
GlobalWin.ExitCode = mf.ProgramRunLoop();
|
||||
}
|
||||
catch (Exception e) when (!Debugger.IsAttached && !VersionInfo.DeveloperBuild && Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
var result = MessageBox.Show(
|
||||
"EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)",
|
||||
$"Fatal error: {e.GetType().Name}",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Exclamation
|
||||
);
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
Global.MovieSession.Movie.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (!Debugger.IsAttached)
|
||||
{
|
||||
new ExceptionBox(e).ShowDialog();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (GlobalWin.Sound != null)
|
||||
{
|
||||
GlobalWin.Sound.Dispose();
|
||||
GlobalWin.Sound = null;
|
||||
}
|
||||
GlobalWin.GL.Dispose();
|
||||
Input.Cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
private static PlatformSpecificMainLoopCrashHandler mainLoopCrashHandler = EXE_PROJECT.PlatformLinkedLibSingleton.RunningOnUnix
|
||||
? (PlatformSpecificMainLoopCrashHandler) new UnixMonoMainLoopCrashHandler()
|
||||
: (PlatformSpecificMainLoopCrashHandler) new Win32MainLoopCrashHandler();
|
||||
|
||||
//NoInlining should keep this code from getting jammed into Main() which would create dependencies on types which havent been setup by the resolver yet... or something like that
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
|
||||
static int SubMain(string[] args)
|
||||
|
@ -324,8 +209,57 @@ namespace BizHawk.Client.EmuHawk
|
|||
SetDllDirectory(dllDir);
|
||||
}
|
||||
|
||||
// Using a simple conditional to skip the single-instancing step caused crashes on GNU+Linux, even though the single-instancing step wasn't being executed. Something about the way instantiation works in C# means this workaround is possible.
|
||||
mainLoopCrashHandler.TryCatchFinally(args);
|
||||
try
|
||||
{
|
||||
if (Global.Config.SingleInstanceMode)
|
||||
{
|
||||
try
|
||||
{
|
||||
new SingleInstanceController(args).Run(args);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
// Eat it, MainForm disposed itself and Run attempts to dispose of itself. Eventually we would want to figure out a way to prevent that, but in the meantime it is harmless, so just eat the error
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var mf = new MainForm(args))
|
||||
{
|
||||
var title = mf.Text;
|
||||
mf.Show();
|
||||
mf.Text = title;
|
||||
try
|
||||
{
|
||||
GlobalWin.ExitCode = mf.ProgramRunLoop();
|
||||
}
|
||||
catch (Exception e) when (Global.MovieSession.Movie.IsActive && !(Debugger.IsAttached || VersionInfo.DeveloperBuild))
|
||||
{
|
||||
var result = MessageBox.Show(
|
||||
"EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)",
|
||||
$"Fatal error: {e.GetType().Name}",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Exclamation
|
||||
);
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
Global.MovieSession.Movie.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (!Debugger.IsAttached)
|
||||
{
|
||||
new ExceptionBox(e).ShowDialog();
|
||||
}
|
||||
finally
|
||||
{
|
||||
GlobalWin.Sound?.Dispose();
|
||||
GlobalWin.Sound = null;
|
||||
GlobalWin.GL.Dispose();
|
||||
Input.Cleanup();
|
||||
}
|
||||
|
||||
//cleanup:
|
||||
//cleanup IGL stuff so we can get better refcounts when exiting process, for debugging
|
||||
|
|
Loading…
Reference in New Issue