mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-19 10:01:24 +00:00
More reliably system shutdown
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/ec/trunk@38302 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c30eed0fa0
commit
177efca91b
8 changed files with 103 additions and 31 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2015-01-26 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
* GNUmakefile.preamble: fixup gcc flag filtering
|
||||
* EcClientI.h:
|
||||
* EcClientI.m:
|
||||
* EcCommand.m:
|
||||
* EcControl.m:
|
||||
* EcProcess.h:
|
||||
* EcProcess.m:
|
||||
Implement forced kill by -terminate method if a client fails to
|
||||
close down gracefully within 30 seconds.
|
||||
|
||||
2015-01-19 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
|
||||
* GNUmakefile.preamble: Fix wrong option letter in sed command.
|
||||
|
|
|
@ -40,9 +40,9 @@
|
|||
@interface EcClientI : NSObject
|
||||
{
|
||||
id<CmdClient> theServer;
|
||||
id obj;
|
||||
NSString *name;
|
||||
NSDate *lastUnanswered; /* Last unanswered ping. */
|
||||
id obj; /* The proxy object of client. */
|
||||
NSString *name; /* The name of the client. */
|
||||
NSDate *lastUnanswered; /* Last unanswered ping. */
|
||||
unsigned fwdSequence; /* Last ping sent TO client. */
|
||||
unsigned revSequence; /* Last gnip sent BY client. */
|
||||
NSMutableSet *files; /* Want update info for these. */
|
||||
|
@ -50,6 +50,7 @@
|
|||
BOOL pingOk; /* Can remote end accept ping? */
|
||||
BOOL transient; /* Is this a transient client? */
|
||||
BOOL unregistered; /* Has client unregistered? */
|
||||
int processIdentifier; /* Process ID if known (or 0). */
|
||||
}
|
||||
- (NSComparisonResult) compare: (EcClientI*)other;
|
||||
- (NSData*) config;
|
||||
|
@ -62,9 +63,11 @@
|
|||
- (NSString*) name;
|
||||
- (id) obj;
|
||||
- (void) ping;
|
||||
- (int) processIdentifier;
|
||||
- (void) setConfig: (NSData*)c;
|
||||
- (void) setName: (NSString*)n;
|
||||
- (void) setObj: (id)o;
|
||||
- (void) setProcessIdentifier: (int)p;
|
||||
- (void) setTransient: (BOOL)flag;
|
||||
- (void) setUnregistered: (BOOL)flag;
|
||||
- (BOOL) transient;
|
||||
|
|
10
EcClientI.m
10
EcClientI.m
|
@ -164,6 +164,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (int) processIdentifier
|
||||
{
|
||||
return processIdentifier;
|
||||
}
|
||||
|
||||
- (void) setConfig: (NSData*)c
|
||||
{
|
||||
ASSIGN(config, c);
|
||||
|
@ -179,6 +184,11 @@
|
|||
ASSIGN(obj, o);
|
||||
}
|
||||
|
||||
- (void) setProcessIdentifier: (int)p
|
||||
{
|
||||
processIdentifier = p;
|
||||
}
|
||||
|
||||
- (void) setTransient: (BOOL)flag
|
||||
{
|
||||
transient = flag ? YES : NO;
|
||||
|
|
59
EcCommand.m
59
EcCommand.m
|
@ -129,7 +129,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
NSArray *launchOrder;
|
||||
NSDictionary *environment;
|
||||
NSMutableDictionary *launches;
|
||||
NSMutableSet *launching;
|
||||
NSMutableDictionary *launching;
|
||||
unsigned pingPosition;
|
||||
NSTimer *terminating;
|
||||
NSDate *lastUnanswered;
|
||||
|
@ -171,6 +171,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
from: (NSString*)s
|
||||
to: (NSString*)d
|
||||
type: (EcLogType)t;
|
||||
- (void) killAll;
|
||||
- (void) launch;
|
||||
- (void) logMessage: (NSString*)msg
|
||||
type: (EcLogType)t
|
||||
|
@ -1776,7 +1777,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
host = RETAIN([[NSHost currentHost] wellKnownName]);
|
||||
clients = [[NSMutableArray alloc] initWithCapacity: 10];
|
||||
launches = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
||||
launching = [[NSMutableSet alloc] initWithCapacity: 10];
|
||||
launching = [[NSMutableDictionary alloc] initWithCapacity: 10];
|
||||
|
||||
timer = [NSTimer scheduledTimerWithTimeInterval: 5.0
|
||||
target: self
|
||||
|
@ -1788,6 +1789,32 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) killAll
|
||||
{
|
||||
#ifndef __MINGW__
|
||||
NSUInteger i = [clients count];
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
while (i-- > 0)
|
||||
{
|
||||
EcClientI *c;
|
||||
|
||||
c = [clients objectAtIndex: i];
|
||||
if (nil != c)
|
||||
{
|
||||
int p = [c processIdentifier];
|
||||
|
||||
if (p > 0)
|
||||
{
|
||||
kill(p, SIGKILL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) launch
|
||||
{
|
||||
if (launchInfo != nil)
|
||||
|
@ -1857,6 +1884,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
NSDictionary *addE = [taskInfo objectForKey: @"AddE"];
|
||||
NSDictionary *setE = [taskInfo objectForKey: @"SetE"];
|
||||
NSString *failed = nil;
|
||||
NSTask *task = nil;
|
||||
NSString *m;
|
||||
|
||||
/* As a convenience, the 'Home' option sets the -HomeDirectory
|
||||
|
@ -1878,11 +1906,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
/* Record time of launch start and the fact that this is launching.
|
||||
*/
|
||||
[launches setObject: now forKey: key];
|
||||
if (nil == [launching member: key])
|
||||
{
|
||||
[launching addObject: key];
|
||||
}
|
||||
else
|
||||
if (nil != [launching objectForKey: key])
|
||||
{
|
||||
NSString *managedObject;
|
||||
EcAlarm *a;
|
||||
|
@ -1901,10 +1925,12 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
additionalText: @"failed to register after launch"];
|
||||
[self alarm: a];
|
||||
}
|
||||
task = [NSTask new];
|
||||
[launching setObject: task forKey: key];
|
||||
RELEASE(task);
|
||||
|
||||
if (prog != nil && [prog length] > 0)
|
||||
{
|
||||
NSTask *task;
|
||||
NSFileHandle *hdl;
|
||||
|
||||
if (setE != nil)
|
||||
|
@ -1922,7 +1948,6 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
[e addEntriesFromDictionary: addE];
|
||||
env = AUTORELEASE(e);
|
||||
}
|
||||
task = [NSTask new];
|
||||
[task setEnvironment: env];
|
||||
hdl = [NSFileHandle fileHandleWithNullDevice];
|
||||
NS_DURING
|
||||
|
@ -1963,7 +1988,6 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
[self information: m from: nil to: nil type: LT_AUDIT];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
RELEASE(task);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2063,8 +2087,8 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
|
||||
if ([clients count] > 0)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned j;
|
||||
NSUInteger i;
|
||||
NSUInteger j;
|
||||
NSMutableArray *a;
|
||||
|
||||
/* Now we tell all connected clients to quit.
|
||||
|
@ -2202,10 +2226,12 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
RELEASE(obj);
|
||||
[clients sortUsingSelector: @selector(compare:)];
|
||||
|
||||
[obj setProcessIdentifier: [c processIdentifier]];
|
||||
|
||||
/* This client has launched ... remove it from the set of launching
|
||||
* clients.
|
||||
*/
|
||||
[launching removeObject: n];
|
||||
[launching removeObjectForKey: n];
|
||||
|
||||
/*
|
||||
* If this client is in the list of launchable clients, set
|
||||
|
@ -2294,7 +2320,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
NSDate *when;
|
||||
|
||||
|
||||
/* We tell all connected clients to quit.
|
||||
/* We tell all connected clients to quit ... allow at most 30 seconds.
|
||||
*/
|
||||
a = [[clients mutableCopy] autorelease];
|
||||
i = [a count];
|
||||
|
@ -2616,7 +2642,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
*/
|
||||
- (void) terminate: (NSTimer*)t
|
||||
{
|
||||
if (terminating == nil)
|
||||
if (nil == terminating)
|
||||
{
|
||||
[self information: @"Handling shutdown."
|
||||
from: nil
|
||||
|
@ -2638,12 +2664,13 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
{
|
||||
NSDate *when = (NSDate*)[t userInfo];
|
||||
|
||||
if ([when timeIntervalSinceNow] < -60.0)
|
||||
if ([when timeIntervalSinceNow] < -30.0)
|
||||
{
|
||||
[[self cmdLogFile: logname]
|
||||
puts: @"Final shutdown.\n"];
|
||||
[terminating invalidate];
|
||||
terminating = nil;
|
||||
[self killAll];
|
||||
[self cmdQuit: tStatus];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2169,7 +2169,7 @@ static NSString* cmdWord(NSArray* a, unsigned int pos)
|
|||
}
|
||||
}
|
||||
|
||||
- (void) requestConfigFor: (id<CmdConfig>)c
|
||||
- (oneway void) requestConfigFor: (id<CmdConfig>)c
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
10
EcProcess.h
10
EcProcess.h
|
@ -231,6 +231,7 @@ typedef enum {
|
|||
@protocol CmdClient <CmdPing,CmdConfig>
|
||||
- (oneway void) cmdMesgData: (in bycopy NSData*)dat from: (NSString*)name;
|
||||
- (oneway void) cmdQuit: (NSInteger)status;
|
||||
- (int) processIdentifier;
|
||||
@end
|
||||
|
||||
/** Messages a Command logging process can be expected to handle.
|
||||
|
@ -268,7 +269,10 @@ typedef enum {
|
|||
- (oneway void) reply: (NSString*)msg
|
||||
to: (NSString*)n
|
||||
from: (NSString*)c;
|
||||
/** Shut down the Command server and all its clients */
|
||||
/** Shut down the Command server and all its clients.<br />
|
||||
* Clients which fail to shut down gracefully within 30 seconds
|
||||
* make be killed.
|
||||
*/
|
||||
- (oneway void) terminate;
|
||||
|
||||
/** This is an exceptional method which may be used without registering
|
||||
|
@ -951,6 +955,10 @@ extern NSString* cmdVersion(NSString *ver);
|
|||
- (void) cmdMesgnodebug: (NSArray*)msg;
|
||||
- (void) cmdMesgstatus: (NSArray*)msg;
|
||||
|
||||
/** Returns the system process identifier for the client process.
|
||||
*/
|
||||
- (int) processIdentifier;
|
||||
|
||||
/**
|
||||
* Returns a proxy object to a[n automatically managed] server process.<br />
|
||||
* The serverName must previously have been registered using the
|
||||
|
|
31
EcProcess.m
31
EcProcess.m
|
@ -1032,11 +1032,13 @@ findMode(NSDictionary* d, NSString* s)
|
|||
|
||||
+ (NSMutableDictionary*) ecInitialDefaults
|
||||
{
|
||||
NSProcessInfo *pi;
|
||||
id objects[2];
|
||||
id keys[2];
|
||||
NSString *prefix;
|
||||
|
||||
objects[0] = [[NSProcessInfo processInfo] processName];
|
||||
pi = [NSProcessInfo processInfo];
|
||||
objects[0] = [pi processName];
|
||||
objects[1] = @".";
|
||||
prefix = EC_DEFAULTS_PREFIX;
|
||||
if (nil == prefix)
|
||||
|
@ -1623,6 +1625,17 @@ static NSString *noFiles = @"No log files to archive";
|
|||
[alarmDestination unmanage: managedObject];
|
||||
}
|
||||
|
||||
- (int) processIdentifier
|
||||
{
|
||||
static int pi = 0;
|
||||
|
||||
if (0 == pi)
|
||||
{
|
||||
pi = [[NSProcessInfo processInfo] processIdentifier];
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
|
||||
- (void) setCmdInterval: (NSTimeInterval)interval
|
||||
{
|
||||
if (interval > 60.0)
|
||||
|
@ -2620,9 +2633,9 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
|
|||
}
|
||||
}
|
||||
|
||||
- (void) cmdGnip: (id <CmdPing>)from
|
||||
sequence: (unsigned)num
|
||||
extra: (NSData*)data
|
||||
- (oneway void) cmdGnip: (id <CmdPing>)from
|
||||
sequence: (unsigned)num
|
||||
extra: (in bycopy NSData*)data
|
||||
{
|
||||
[self cmdDbg: cmdConnectDbg msg: @"cmdGnip: %lx sequence: %u extra: %lx",
|
||||
(unsigned long)from, num, (unsigned long)data];
|
||||
|
@ -3386,9 +3399,9 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
|
|||
}
|
||||
|
||||
|
||||
- (void) cmdPing: (id <CmdPing>)from
|
||||
sequence: (unsigned)num
|
||||
extra: (NSData*)data
|
||||
- (oneway void) cmdPing: (id <CmdPing>)from
|
||||
sequence: (unsigned)num
|
||||
extra: (in bycopy NSData*)data
|
||||
{
|
||||
[self cmdDbg: cmdConnectDbg msg: @"cmdPing: %lx sequence: %u extra: %lx",
|
||||
(unsigned long)from, num, (unsigned long)data];
|
||||
|
@ -4057,7 +4070,7 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
|
|||
format: @"Illegal method call"];
|
||||
}
|
||||
|
||||
- (void) requestConfigFor: (id<CmdConfig>)c
|
||||
- (oneway void) requestConfigFor: (id<CmdConfig>)c
|
||||
{
|
||||
[NSException raise: NSGenericException
|
||||
format: @"Illegal method call"];
|
||||
|
@ -4071,7 +4084,7 @@ NSLog(@"Ignored attempt to set timer interval to %g ... using 10.0", interval);
|
|||
format: @"Illegal method call"];
|
||||
}
|
||||
|
||||
- (void) updateConfig: (NSData*)info
|
||||
- (oneway void) updateConfig: (in bycopy NSData*)info
|
||||
{
|
||||
id plist = [NSPropertyListSerialization
|
||||
propertyListWithData: info
|
||||
|
|
|
@ -48,7 +48,7 @@ LIBRARIES_DEPEND_UPON += $(ECCL_LIBS)
|
|||
# Extras for when building with SNMP support
|
||||
#
|
||||
ifeq ($(WITH_NET_SNMP),yes)
|
||||
EcAlarmSinkSNMP.m_FILE_FLAGS += $(shell net-snmp-config --cflags | sed -e 's/-l[^ ]*//g' | sed -e 's/-fstack-protect-strong//g')
|
||||
EcAlarmSinkSNMP.m_FILE_FLAGS += $(shell net-snmp-config --cflags | sed -e 's/-l[^ ]*//g' | sed -e 's/-fstack-protector-strong//g')
|
||||
LIBRARIES_DEPEND_UPON += $(shell net-snmp-config --agent-libs)
|
||||
endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue