diff --git a/ChangeLog b/ChangeLog index b70c989..d7d3e05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2020-04-02 Richard Frith-Macdonald + + * EcCommand.m: + * EcLogger.m: + * EcProcess.h: + * EcProcess.m: + Remove obsolete methods for registration/unregistration. Change code + to refrain from registering with Command server if in the process of + shutting down, and to refrain from attempting an unregistration if + not already registered. The hope is that this will prevent a race + condition where loss of connection to the Command server can cause a + shutdown and re-register during the shutdown fooling the Command + server into thinking the process is still running. + 2020-03-23 Richard Frith-Macdonald * EcProcess.h: diff --git a/EcCommand.m b/EcCommand.m index e1b9257..284adcf 100644 --- a/EcCommand.m +++ b/EcCommand.m @@ -549,8 +549,6 @@ static NSMutableDictionary *launchInfo = nil; - (void) quitAll: (NSDate*)by; - (void) reLaunch: (NSTimer*)t; - (void) requestConfigFor: (id)c; -- (NSData*) registerClient: (id)c - name: (NSString*)n; - (NSData*) registerClient: (id)c name: (NSString*)n transient: (BOOL)t; @@ -563,7 +561,6 @@ static NSMutableDictionary *launchInfo = nil; - (void) _tryLaunch: (NSTimer*)t; - (void) tryLaunchSoon; - (void) unregisterByObject: (id)obj; -- (void) unregisterByName: (NSString*)n; - (void) unregisterClient: (EcClientI*)o gracefully: (BOOL)clean; - (void) update; - (void) updateConfig: (NSData*)data; @@ -2947,12 +2944,6 @@ NSLog(@"Problem %@", localException); } } -- (NSData*) registerClient: (id)c - name: (NSString*)n -{ - return [self registerClient: c name: n transient: NO]; -} - - (NSData*) registerClient: (id)c name: (NSString*)n transient: (BOOL)t @@ -3032,6 +3023,10 @@ NSLog(@"Problem %@", localException); } else { + /* Rejecting means the client is not registered (and therefore should + * not be told to quit when the objct is deallocated. + */ + [obj setUnregistered: YES]; RELEASE(obj); m = [NSString stringWithFormat: @"%@ rejected new server with name '%@' on %@\n", @@ -4024,14 +4019,10 @@ NSLog(@"Problem %@", localException); { EcClientI *o = [self findIn: clients byObject: obj]; - [self unregisterClient: o gracefully: YES]; -} - -- (void) unregisterByName: (NSString*)n -{ - EcClientI *o = [self findIn: clients byName: n]; - - [self unregisterClient: o gracefully: YES]; + if (o != nil) + { + [self unregisterClient: o gracefully: YES]; + } } - (void) update diff --git a/EcLogger.m b/EcLogger.m index 8595940..9866289 100644 --- a/EcLogger.m +++ b/EcLogger.m @@ -147,7 +147,7 @@ static NSArray *modes; id server; server = (id)[EcProc server: name]; - [server registerClient: self name: cmdLogName()]; + [server registerClient: self name: cmdLogName() transient: NO]; } /* Should only be called on main thread, but doesn't matter. diff --git a/EcProcess.h b/EcProcess.h index 4d60c47..48b939e 100644 --- a/EcProcess.h +++ b/EcProcess.h @@ -157,9 +157,9 @@ typedef enum { type: (EcLogType)t for: (id)o; - (bycopy NSData*) registerClient: (id)c - name: (NSString*)n; + name: (NSString*)n + transient: (BOOL)t; - (void) unregisterByObject: (id)obj; -- (void) unregisterByName: (NSString*)n; @end @protocol Console diff --git a/EcProcess.m b/EcProcess.m index b256c5d..e562105 100644 --- a/EcProcess.m +++ b/EcProcess.m @@ -241,6 +241,7 @@ static BOOL configInProgress = NO; static BOOL cmdFlagDaemon = NO; static BOOL cmdFlagTesting = NO; static BOOL cmdIsRunning = NO; +static BOOL cmdIsRegistered = NO; static BOOL cmdKeepStderr = NO; static BOOL cmdKillDebug = NO; static NSString *cmdBase = nil; @@ -1966,10 +1967,12 @@ findMode(NSDictionary* d, NSString* s) [connection invalidate]; } DESTROY(cmdServer); + cmdIsRegistered = NO; } - (void) _connectionRegistered { + cmdIsRegistered = YES; [alarmDestination domanage: nil]; } @@ -3411,6 +3414,29 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval); rootProxyForConnectionWithRegisteredName: name host: host usingNameServer: ns]; + [proxy setProtocolForProxy: @protocol(Command)]; + if (nil == proxy) + { + NSLog(@"Unable to connect to Command server"); + } + else + { + NSConnection *connection; + + ASSIGN(cmdServer, proxy); + connection = [cmdServer connectionForProxy]; + [connection enableMultipleThreads]; + if (nil == alarmDestination) + { + alarmDestination = [EcAlarmDestination new]; + } + [[self ecAlarmDestination] setDestination: cmdServer]; + [[NSNotificationCenter defaultCenter] + addObserver: self + selector: @selector(cmdConnectionBecameInvalid:) + name: NSConnectionDidDieNotification + object: connection]; + } } NS_HANDLER { @@ -3420,12 +3446,15 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval); } NS_ENDHANDLER - if (proxy != nil) + /* We only register and fetch new configuration information + * if we are NOT in the process of shutting down: a process + * which is shutting down should only use the Command server + * for logging/alerting purposes. + */ + if (proxy != nil && 0.0 == beganQuitting) { NSMutableDictionary *r = nil; - [proxy setProtocolForProxy: @protocol(Command)]; - NS_DURING { NSData *d; @@ -3466,26 +3495,11 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval); } else if ([r objectForKey: @"back-off"] != nil) { - NSLog(@"Unable to connect to Command server ..." + NSLog(@"Unable to register with Command server ..." @" back-off"); } else { - NSConnection *connection; - - cmdServer = [proxy retain]; - connection = [cmdServer connectionForProxy]; - [connection enableMultipleThreads]; - if (nil == alarmDestination) - { - alarmDestination = [EcAlarmDestination new]; - } - [[self ecAlarmDestination] setDestination: cmdServer]; - [[NSNotificationCenter defaultCenter] - addObserver: self - selector: @selector(cmdConnectionBecameInvalid:) - name: NSConnectionDidDieNotification - object: connection]; [self _update: r]; /* If we just connected to the command server, @@ -3499,10 +3513,6 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval); } } } - else - { - NSLog(@"Unable to connect to Command server ... not found"); - } } connecting = NO; if (nil == cmdLast && nil == cmdServer && YES == [self cmdIsClient]) @@ -3532,7 +3542,11 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval); { NS_DURING { - [cmdServer unregisterByObject: self]; + if (cmdIsRegistered) + { + cmdIsRegistered = NO; + [cmdServer unregisterByObject: self]; + } } NS_HANDLER {