[NSPipe pipe] returning nil (running out of filehandles?)
[NSPipe pipe] returning nil (running out of filehandles?)
- Subject: [NSPipe pipe] returning nil (running out of filehandles?)
- From: Martin Redington <email@hidden>
- Date: Wed, 2 Apr 2008 00:20:04 +0100
I'm running /sbin/md5 via an NSTask on a number of files (3,000 or
so, with a new NSTask each time).
This is on 10.4.11, with Xcode 2.4.1
My Debug and Release builds seem to be running out of filehandles, or
something similar, as evidenced by the following symptoms:
1) [NSPipe pipe] starts to returns nil
2) This always happens at the same point, indicating some kind of
hard resource limit.
3) lsof -p PID shows an increasing number of open filehandles during
the md5 calculation
My md5 method looks more or less as pasted below (I've stripped a few
irrelevant details and some logging).
The problem always occurs on something like the 250th invocation of
the md5ChecksumForPath method (its always the same, but I just
cleared the log).
Oddly, when run in the debugger, I don't seem to see this issue, and
the process runs to completion, even though the number of open files,
as shown by lsof, reaches 3000+
Once it completes, all of the extra filehandles get released (it's
back down to 90 right now).
Am I missing some kind of cleanup here?
I realise there are probably alternatives to NSTask/md5 here (such as
reading the files myself, and calling the MD5 from <openssl/md5.h>),
but this issue apart, what I've got right now seems to work fine.
One other piece of info - this all happens in a worker thread. In the
case of running under the debugger, this thread has terminated now
that the process is complete, so the cleanup may have occurred then.
========
- (NSString *) md5ChecksumForPath:(NSString *)absolutePath
{
NSString *md5Checksum = nil;
md5Count++;
// I added the pool to try and make sure that old pipes get
autoreleased.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *args = [NSArray arrayWithObjects:@"-q", absolutePath,
nil];
NSTask *md5Task = [[NSTask alloc] init];
[md5Task setLaunchPath:@"/sbin/md5"];
[md5Task setArguments:args];
// This starts to return nil, always at the same point
NSPipe *thePipe = [NSPipe pipe];
NSFileHandle *readHandle = [thePipe fileHandleForReading];
// Actual failure occurs here. Throws setObject:forKey: with nil
object.
[md5Task setStandardOutput:thePipe];
[md5Task launch];
NSData *outputData = nil;
while ((outputData = [readHandle availableData]) && [outputData
length]) {
md5Checksum = [[NSString alloc] initWithData:outputData
encoding:NSUTF8StringEncoding];
}
[md5Task release];
[pool release];
[md5Checksum autorelease];
return md5Checksum;
}
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden