Author: rfm
Date: Mon Jan 26 13:50:42 2015
New Revision: 38302

URL: http://svn.gna.org/viewcvs/gnustep?rev=38302&view=rev
Log:
More reliably system shutdown

Modified:
    libs/ec/trunk/ChangeLog
    libs/ec/trunk/EcClientI.h
    libs/ec/trunk/EcClientI.m
    libs/ec/trunk/EcCommand.m
    libs/ec/trunk/EcControl.m
    libs/ec/trunk/EcProcess.h
    libs/ec/trunk/EcProcess.m
    libs/ec/trunk/GNUmakefile.preamble

Modified: libs/ec/trunk/ChangeLog
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/ChangeLog?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/ChangeLog     (original)
+++ libs/ec/trunk/ChangeLog     Mon Jan 26 13:50:42 2015
@@ -1,3 +1,14 @@
+2015-01-26  Richard Frith-Macdonald <[email protected]>
+        * 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  <[email protected]>
 
        * GNUmakefile.preamble: Fix wrong option letter in sed command.

Modified: libs/ec/trunk/EcClientI.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcClientI.h?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/EcClientI.h   (original)
+++ libs/ec/trunk/EcClientI.h   Mon Jan 26 13:50:42 2015
@@ -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;

Modified: libs/ec/trunk/EcClientI.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcClientI.m?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/EcClientI.m   (original)
+++ libs/ec/trunk/EcClientI.m   Mon Jan 26 13:50:42 2015
@@ -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;

Modified: libs/ec/trunk/EcCommand.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcCommand.m?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/EcCommand.m   (original)
+++ libs/ec/trunk/EcCommand.m   Mon Jan 26 13:50:42 2015
@@ -129,7 +129,7 @@
   NSArray               *launchOrder;
   NSDictionary         *environment;
   NSMutableDictionary  *launches;
-  NSMutableSet         *launching;
+  NSMutableDictionary   *launching;
   unsigned             pingPosition;
   NSTimer              *terminating;
   NSDate               *lastUnanswered;
@@ -171,6 +171,7 @@
                from: (NSString*)s
                  to: (NSString*)d
                type: (EcLogType)t;
+- (void) killAll;
 - (void) launch;
 - (void) logMessage: (NSString*)msg
               type: (EcLogType)t
@@ -1776,7 +1777,7 @@
       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
@@ -1786,6 +1787,32 @@
       [self timedOut: nil];
     }
   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
@@ -1857,6 +1884,7 @@
          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 @@
          /* 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 @@
                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 @@
                  [e addEntriesFromDictionary: addE];
                  env = AUTORELEASE(e);
                }
-             task = [NSTask new];
              [task setEnvironment: env];
              hdl = [NSFileHandle fileHandleWithNullDevice];
              NS_DURING
@@ -1963,7 +1988,6 @@
                   [self information: m from: nil to: nil type: LT_AUDIT];
                }
              NS_ENDHANDLER
-             RELEASE(task);
            }
          else
            {
@@ -2063,8 +2087,8 @@
 
   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 @@
       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 @@
       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 @@
  */
 - (void) terminate: (NSTimer*)t
 {
-  if (terminating == nil)
+  if (nil == terminating)
     {
       [self information: @"Handling shutdown."
                   from: nil
@@ -2638,12 +2664,13 @@
     {
       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];
        }
     }

Modified: libs/ec/trunk/EcControl.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcControl.m?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/EcControl.m   (original)
+++ libs/ec/trunk/EcControl.m   Mon Jan 26 13:50:42 2015
@@ -2169,7 +2169,7 @@
     }
 }
 
-- (void) requestConfigFor: (id<CmdConfig>)c
+- (oneway void) requestConfigFor: (id<CmdConfig>)c
 {
   return;
 }

Modified: libs/ec/trunk/EcProcess.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcProcess.h?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/EcProcess.h   (original)
+++ libs/ec/trunk/EcProcess.h   Mon Jan 26 13:50:42 2015
@@ -231,6 +231,7 @@
 @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 @@
 - (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 @@
 - (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

Modified: libs/ec/trunk/EcProcess.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcProcess.m?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/EcProcess.m   (original)
+++ libs/ec/trunk/EcProcess.m   Mon Jan 26 13:50:42 2015
@@ -1032,11 +1032,13 @@
 
 + (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)
@@ -1621,6 +1623,17 @@
 - (oneway void) unmanage: (in bycopy NSString*)managedObject
 {
   [alarmDestination unmanage: managedObject];
+}
+
+- (int) processIdentifier
+{
+  static int    pi = 0;
+
+  if (0 == pi)
+    {
+      pi = [[NSProcessInfo processInfo] processIdentifier];
+    }
+  return pi;
 }
 
 - (void) setCmdInterval: (NSTimeInterval)interval
@@ -2620,9 +2633,9 @@
     }
 }
 
-- (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 @@
 }
 
 
-- (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 @@
              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 @@
              format: @"Illegal method call"];
 }
 
-- (void) updateConfig: (NSData*)info
+- (oneway void) updateConfig: (in bycopy NSData*)info
 {
   id   plist = [NSPropertyListSerialization
     propertyListWithData: info

Modified: libs/ec/trunk/GNUmakefile.preamble
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/GNUmakefile.preamble?rev=38302&r1=38301&r2=38302&view=diff
==============================================================================
--- libs/ec/trunk/GNUmakefile.preamble  (original)
+++ libs/ec/trunk/GNUmakefile.preamble  Mon Jan 26 13:50:42 2015
@@ -48,7 +48,7 @@
 # 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
 


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to