From 2e3e0abdff6fd3fc8294b162b487b4a04fbce8b7 Mon Sep 17 00:00:00 2001 From: "kenneth@hexad.dk" Date: Thu, 17 Nov 2011 19:56:41 +0000 Subject: [PATCH] A bit of a hack, but now the main message loop is aborted if the application hangs after closing. This should not cause any problems because the timer is started at the very last moment, and there should be no work to do after invocation but simply discard the hidden window. The abort is picked up so the program cleanup-on-exit code is executed as normal. git-svn-id: https://duplicati.googlecode.com/svn/trunk@999 59da171f-624f-0410-aa54-27559c288bec --- Duplicati/GUI/MainForm.cs | 16 +++++++++++++++- Duplicati/GUI/Program.cs | 23 ++++++++++++++++++----- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Duplicati/GUI/MainForm.cs b/Duplicati/GUI/MainForm.cs index 227cbbfbc..b4af92564 100644 --- a/Duplicati/GUI/MainForm.cs +++ b/Duplicati/GUI/MainForm.cs @@ -319,6 +319,16 @@ namespace Duplicati.GUI { TrayIcon_MouseClick(sender, e); } + + private static void AbortOwnThread(object thread) + { + System.Threading.Thread.Sleep(5000); + if (Program.IsRunningMainLoop) + { + Program.IsRunningMainLoop = false; + ((System.Threading.Thread)thread).Abort(); + } + } private void TrayIcon_MouseClick(object sender, MouseEventArgs e) { @@ -521,7 +531,11 @@ namespace Duplicati.GUI Program.SingleInstance.SecondInstanceDetected -= new SingleInstance.SecondInstanceDelegate(SingleInstance_SecondInstanceDetected); EnsureBackupIsTerminated(e.CloseReason == CloseReason.UserClosing ? CloseReason.ApplicationExitCall : e.CloseReason); - } + + //The form occasionally hangs on Mono, so we force kill it after 5 secs if it did not quit itself + if (Library.Utility.Utility.IsMono) + new System.Threading.Thread(AbortOwnThread).Start (System.Threading.Thread.CurrentThread); + } private void SingleInstance_SecondInstanceDetected(string[] commandlineargs) { diff --git a/Duplicati/GUI/Program.cs b/Duplicati/GUI/Program.cs index 627ad53f7..b0886adeb 100644 --- a/Duplicati/GUI/Program.cs +++ b/Duplicati/GUI/Program.cs @@ -97,8 +97,14 @@ namespace Duplicati.GUI /// A value describing if Duplicati is running without a tray /// public static bool TraylessMode = Library.Utility.Utility.IsClientLinux ? true : false; - - /// + + /// + /// A flag indicating if the main message loop is still running, + /// used to force exit when running on OSX + /// + public static bool IsRunningMainLoop; + + /// /// The main entry point for the application. /// [STAThread] @@ -321,13 +327,20 @@ namespace Duplicati.GUI DisplayHelper = new MainForm(); DisplayHelper.InitialArguments = args; - + + Program.IsRunningMainLoop = true; Application.Run(DisplayHelper); + Program.IsRunningMainLoop = false; } catch (Exception ex) { - MessageBox.Show(string.Format(Strings.Program.SeriousError, ex.ToString()), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); - } + //If the helper thread aborts the main thread, it also sets IsRunningMainLoop to false + // and in that case we accept the abort call + if (ex is System.Threading.ThreadAbortException && !Program.IsRunningMainLoop) + System.Threading.Thread.ResetAbort(); + else + MessageBox.Show(string.Format(Strings.Program.SeriousError, ex.ToString()), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); + } try {