site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com On 2011 Mar 22, at 17:12, Antoine Missout wrote:
Check this: http://stackoverflow.com/questions/1321219/receiving-power-notifications-esp...
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.htm... 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 (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... This email sent to site_archiver@lists.apple.com