From 0c93e18a0c35cf930c58ec2b578e76de8d088e67 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Tue, 21 Feb 2023 16:37:30 -0800 Subject: [PATCH] Don't throw Objective C exception when quitting MacVim Currently when quitting MacVim, MMVimController will throw an exception in `sendMessage:`. This is because MMAppController's handler for quitting simply closes the connection, terminates the Vim processes and quit; it doesn't individually shut down each Vim controller cleanly. This is actually ok because we are quitting the app anyway, and it's not terrible to just let the OS clean up (applicationWillTerminate also has a 5 second executation timer set by macOS), but we do need to make sure Vim controllers won't be trying to handle the now invalid connections. Currently the exceptions will be caught by an exception handler, but it's still not great, and could be confused with a bug, especially if logging is enabled. Add a way to set `isInitialized` to NO when shutting down, so that the controllers will be blocked from trying to send connections. --- src/MacVim/MMAppController.m | 9 +++++++++ src/MacVim/MMVimController.h | 1 + src/MacVim/MMVimController.m | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 904db5c161..5cf6cbb1f4 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -759,6 +759,15 @@ - (void)applicationWillTerminate:(NSNotification *)notification andEventID:'MOD ']; #endif + // We are hard shutting down the app here by terminating all Vim processes + // and then just quit without cleanly removing each Vim controller. We + // don't want the straggler controllers to still interact with the now + // invalid connections, so we just mark them as uninitialized. + for (NSUInteger i = 0, count = [vimControllers count]; i < count; ++i) { + MMVimController *vc = [vimControllers objectAtIndex:i]; + [vc uninitialize]; + } + // This will invalidate all connections (since they were spawned from this // connection). [connection invalidate]; diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h index c1dda229a7..6ab169adc8 100644 --- a/src/MacVim/MMVimController.h +++ b/src/MacVim/MMVimController.h @@ -57,6 +57,7 @@ } - (id)initWithBackend:(id)backend pid:(int)processIdentifier; +- (void)uninitialize; - (unsigned)vimControllerId; - (id)backendProxy; - (int)pid; diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index c9e1063cbd..891ec617e7 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -248,6 +248,15 @@ - (void)dealloc [super dealloc]; } +/// This should only be called by MMAppController when it's doing an app quit. +/// We just wait for all Vim processes to terminate instad of individually +/// closing each MMVimController. We simply unset isInitialized to prevent it +/// from handling and sending messages to now invalid Vim connections. +- (void)uninitialize +{ + isInitialized = NO; +} + - (unsigned)vimControllerId { return identifier;