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