Instantly share code, notes, and snippets.

@abock /AppDelegate.cs Secret
Last active May 26, 2017

Embed
What would you like to do?
Repro case for bxc#52604 (adjust #if in Exit to test both cases)
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using AppKit;
using Foundation;
namespace UnableToExit
{
[Register (nameof (AppDelegate))]
sealed class AppDelegate : NSApplicationDelegate
{
[DllImport ("libc")]
static extern void exit (int c);
[DllImport ("libc")]
static extern void atexit (IntPtr a);
static Action atExitDelegate;
public override void DidFinishLaunching (NSNotification notification)
{
Log ();
atExitDelegate = AtExit;
atexit (Marshal.GetFunctionPointerForDelegate (atExitDelegate));
new Thread (BackgroundThread).Start ();
}
void BackgroundThread (object state)
{
Log ();
InvokeOnMainThread (Exit);
}
void Exit ()
{
#if false
Log ("invoking Environment.Exit");
Environment.Exit (0);
#else
Log ("invoking exit");
exit (0);
#endif
}
void AtExit () => Log ();
void Log (string message = null, [CallerMemberName] string caller = null)
=> Console.WriteLine (
"thread {0}: {1} {2}",
Thread.CurrentThread.ManagedThreadId,
caller,
message);
}
}

Output when exiting via exit:

thread 1: DidFinishLaunching 
thread 4: BackgroundThread 
thread 1: Exit invoking exit
thread 1: AtExit

Expected output when exiting via Environment.Exit:

thread 1: DidFinishLaunching 
thread 4: BackgroundThread 
thread 1: Exit invoking Environment.Exit
thread 1: AtExit

Actual output (does not exit, hangs in Environment.Exit):

thread 1: DidFinishLaunching 
thread 4: BackgroundThread 
thread 1: Exit invoking Environment.Exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment