Author: rfm
Date: Sat Nov  1 10:18:02 2014
New Revision: 38143

URL: http://svn.gna.org/viewcvs/gnustep?rev=38143&view=rev
Log:
try to cope with descriptor leaks

Modified:
    libs/ec/trunk/ChangeLog
    libs/ec/trunk/EcProcess.h
    libs/ec/trunk/EcProcess.m

Modified: libs/ec/trunk/ChangeLog
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/ChangeLog?rev=38143&r1=38142&r2=38143&view=diff
==============================================================================
--- libs/ec/trunk/ChangeLog     (original)
+++ libs/ec/trunk/ChangeLog     Sat Nov  1 10:18:02 2014
@@ -1,3 +1,9 @@
+2014-11-01  Richard Frith-Macdonald <[email protected]>
+
+       * EcProcess.m: Check for descriptor leaks at 1 minute intervals,
+        and shut down if EcDescriptorsMaximum is exceeded or if the
+       process runs out of descriptors.
+
 2014-10-23  Richard Frith-Macdonald <[email protected]>
 
        * EcCommand.m:

Modified: libs/ec/trunk/EcProcess.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcProcess.h?rev=38143&r1=38142&r2=38143&view=diff
==============================================================================
--- libs/ec/trunk/EcProcess.h   (original)
+++ libs/ec/trunk/EcProcess.h   Sat Nov  1 10:18:02 2014
@@ -62,6 +62,19 @@
            <desc>
              Any key of the form EcDebug-xxx turns on the xxx debug level
              on program startup.
+           </desc>
+           <term>EcDescriptorsMaximum</term>
+           <desc>
+              To protect against file descriptor leaks, a process will
+              check for the ability to create a pipe once a minute.<br />
+              If it can't do so, it will shut down with an error message.<br />
+              To increase the chances of a successful shutdown, two
+              descriptors are reserved on the first check, and closed
+              when a shutdown is attempted.<br />
+              If EcDescriptorsMaximum is defined to a positive integer value,
+              it is used to trigger earlier shutdown once the specified
+              number of open file descriptors has been reached, rather
+              than waiting for the operating system imposed limit.
            </desc>
            <term>EcMemory</term>
            <desc>

Modified: libs/ec/trunk/EcProcess.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/ec/trunk/EcProcess.m?rev=38143&r1=38142&r2=38143&view=diff
==============================================================================
--- libs/ec/trunk/EcProcess.m   (original)
+++ libs/ec/trunk/EcProcess.m   Sat Nov  1 10:18:02 2014
@@ -492,6 +492,11 @@
 static NSUInteger      memSlot = 0;
 static NSUInteger      memRoll[10];
 #define        memSize (sizeof(memRoll)/sizeof(*memRoll))
+
+#ifndef __MINGW__
+static int              reservedPipe[2] = { 0, 0 };
+static NSInteger        descriptorsMaximum = 0;
+#endif
 
 
 static NSString*
@@ -1199,6 +1204,10 @@
       [self setCmdInterval: [str floatValue]];
     }
 
+#ifndef __MINGW__
+  descriptorsMaximum = [cmdDefs integerForKey: @"DescriptorsMaximum"];
+#endif
+
   memAllowed = (uint64_t)[cmdDefs integerForKey: @"MemoryAllowed"];
   if (0 == memAllowed || memAllowed > 100000)
     {
@@ -2135,6 +2144,56 @@
 - (void) ecNewMinute: (NSCalendarDate*)when
 {
   struct mallinfo      info;
+
+#ifndef __MINGW__
+  if (NO == cmdIsQuitting)
+    {
+      NSString          *shutdown = nil;
+      int              p[2];
+
+      if (pipe(p) == 0)
+        {
+          if (0 == reservedPipe[1])
+            {
+              reservedPipe[0] = p[0];
+              reservedPipe[1] = p[1];
+            }
+          else
+            {
+              close(p[0]);
+              close(p[1]);
+            }
+          if (descriptorsMaximum > 0)
+            {
+              if (p[0] > descriptorsMaximum || p[1] > descriptorsMaximum)
+                {
+                  shutdown = [NSString stringWithFormat:
+                    @"Open file descriptor limit (%lu) exceeded",
+                    (unsigned long) descriptorsMaximum];
+                }
+            }
+        }
+      else
+        {
+          shutdown = @"Process ran out of file descriptors";
+        }
+      if (nil != shutdown)
+        {
+          /* We hope that closing two reserved file descriptors will allow
+           * us to shut down gracefully and restart.
+           */
+          if (reservedPipe[1] > 0)
+            {
+              close(reservedPipe[0]); reservedPipe[0] = 0;
+              close(reservedPipe[1]); reservedPipe[1] = 0;
+            }
+          [self cmdError: @"%@", shutdown];
+          cmdIsQuitting = YES;
+          [self cmdQuit: -1];
+          return;
+        }
+    }
+#endif
 
   /* We want to be sure we work with reasonably up to date information.
    */
@@ -3300,6 +3359,11 @@
 
 - (void) cmdQuit: (NSInteger)status
 {
+  if (reservedPipe[1] > 0)
+    {
+      close(reservedPipe[0]); reservedPipe[0] = 0;
+      close(reservedPipe[1]); reservedPipe[1] = 0;
+    }
   cmdIsQuitting = YES;
   cmdQuitStatus = status;
   if (cmdPTimer != nil)


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

Reply via email to