Re: How to tell if system shutdown is in process
Re: How to tell if system shutdown is in process
- Subject: Re: How to tell if system shutdown is in process
- From: Jerry Krinock <email@hidden>
- Date: Wed, 23 Mar 2011 11:03:39 -0700
On 2011 Mar 22, at 17:12, Antoine Missout wrote:
> Check this:
> http://stackoverflow.com/questions/1321219/receiving-power-notifications-especially-shutdown-on-mac-osx
Thank you, Antoine. The suggestion there is to use NSWorkspaceWillPowerOffNotification. I didn't think to check Cocoa for this!
Anyhow, NSWorkspaceWillPowerOffNotification doesn't seem to be received by my tool, at least not before it is killed. Another programmer reported in 2007 [1] that NSWorkspaceWillPowerOffNotification seems to not be sent to non-GUI programs, and they were going to report it as a bug. At the end of this message I've pasted in the code of a little test tool. It registers for NSWorkspaceWillPowerOffNotification and also installs a signal handler for SIGTERM, logging when either are received. And it logs a heartbeat every 50 milliseconds so I can see when it was killed.
To make sure that my test process would not be killed when its parent Terminal.app or Xcode.app was quit, I wrote a launchd plist for it, and launched my test process with launchctl. Then I launched a dozen or so big apps, leaving a dirty document in one of them. I clicked Shut Down, got the confirmation dialog, and clicked Shut Down at 00:00 min:sec. Here's what happened…
00:04 Dialog appears asking me about the dirty document. I don't respond.
00:09 Test tool receives SIGTERM
00:30 I respond to the dirty document dialog with "Don't Save"
00:30 Test tool is killed (heartbeats stop)
00:35 Display goes to all blue, spinning progress indicator appears
NSWorkspaceWillPowerOffNotification was never received. Can anyone see anything wrong with my code?
Now, I suspect that if I did this with no other apps open, the time between SIGTERM and kill might be less than a second. I also received a reply off-list from Jerry Jorgensen explaining a robust approach of doing a safe save, leaving a file to indicate if my task was interrupted, etc. I might do that in addition to handling SIGTERM.
Also, it would be nice if there were a function in the API which would tell me BOOL IsShutdownInProgress().
Jerry Krinock
[1] http://www.cocoabuilder.com/archive/cocoa/187479-user-shutdown-or-logout.html?q="shut+down"+logout#187826
MY TEST TOOL……………………………………………
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
@interface Shutdowner : NSObject {}
@end
@implementation Shutdowner
- (void) shutItDown:(NSNotification*)note {
NSLog(@"Got shutdown");
}
- (void)tickTimer:(NSTimer*)timer {
NSRange hmsRange = NSMakeRange(11,8) ;
NSString* hms = [[[NSDate date] description] substringWithRange:hmsRange] ;
NSTimeInterval nowTime = [NSDate timeIntervalSinceReferenceDate] ;
NSInteger nowSecs = (int)nowTime ;
NSInteger millisecs = (nowTime - nowSecs) * 1000 ;
NSString* s = [NSString stringWithFormat:@"%@.%d", hms, millisecs] ;
NSLog(@"Time = %@ seconds", s) ;
}
@end
void handleSIGTERM(int signum) {
NSLog(@"Got signal %d", signum) ;
}
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Shutdowner *shutdowner = [[Shutdowner alloc] init];
// Add signal handler for SIGTERM
(void)signal(SIGTERM, handleSIGTERM) ;
// Register to observe shutdown notification
NSNotificationCenter* wnc = [[NSWorkspace sharedWorkspace] notificationCenter] ;
[wnc addObserver:shutdowner
selector:@selector(shutItDown:)
name:NSWorkspaceWillPowerOffNotification
object:nil];
// Heartbeat
NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:0.05
target:shutdowner
selector:@selector(tickTimer:)
userInfo:nil
repeats:YES] ;
// Run
[[NSRunLoop currentRunLoop] run] ;
// Clean up
[t invalidate] ;
[wnc removeObserver:shutdowner] ;
[shutdowner release] ;
[pool release] ;
return 0 ;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden