Re: CFFileDescriptor fd leak?
Re: CFFileDescriptor fd leak?
- Subject: Re: CFFileDescriptor fd leak?
- From: "A.M." <email@hidden>
- Date: Thu, 20 Aug 2009 19:42:36 -0400
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Aug 20, 2009, at 6:47 PM, Dave Keck wrote:
Hey,
I ran your test code and saw the same results. After tweaking the
code a
bit, I found that to have the kqueues cleaned up, you have to create
a run
loop source for the CFFD, add it to the run loop, and then remove it
from
the run loop. Here's the tweaked code:
==============================
#include <CoreFoundation/CoreFoundation.h>
#include <unistd.h>
#include <sys/event.h>
static void junkCallback(CFFileDescriptorRef fdref, CFOptionFlags
callBackTypes, void *info) {}
int main(int argc, char *argv[])
{
int i = 0;
for (i = 0; i < 3; i++)
{
CFFileDescriptorRef fileDescriptor = nil;
CFRunLoopSourceRef runLoopSource = nil;
NSLog(@"CREATE %d", i);
fileDescriptor = CFFileDescriptorCreate(NULL, 0, false,
junkCallback, NULL);
runLoopSource = CFFileDescriptorCreateRunLoopSource(NULL,
fileDescriptor, 0);
CFRunLoopAddSource([[NSRunLoop currentRunLoop] getCFRunLoop],
runLoopSource, kCFRunLoopDefaultMode);
NSLog(@"DESTROY %d", i);
CFRunLoopRemoveSource([[NSRunLoop currentRunLoop]
getCFRunLoop],
runLoopSource, kCFRunLoopDefaultMode);
CFRelease(runLoopSource);
CFFileDescriptorInvalidate(fileDescriptor);
CFRelease(fileDescriptor);
}
sleep(-1);
return 0;
}
==============================
I'd definitely consider your findings a bug. But I don't think it
poses any
real issue, since CFFileDescriptor is useless unless it's used with
a run
loop.
I'd say a radar is in order...
Hi Dave,
I shaved down the code from the previous email from code which did
indeed add the CFFileDescriptor to the runloop and leaked. However, I
did not remove the source from the runloop manually like you do above
and the Apple example code (http://developer.apple.com/documentation/CoreFoundation/Reference/CFFileDescriptorRef/Reference/reference.html
) doesn't remove the runloop source either. Unfortunately, the code
you laid out above does indeed sometimes leak a single kqueue fd (OS
10.5.8):
rd07:~ alex$ ./davekeck &
[1] 4880
rd07:~ alex$ lsof -p $! | grep KQUEUE
davekeck 4880 alex 4u KQUEUE count=0,
state=0
If I run it with breakpoints on kqueue, close, and kevent in gdb, then
the leak disappears, which indicates that the Apple code has a race
condition. I noticed that close() is called in the
__monitor_file_descriptor__ thread, so I suspect that without the
thread created from the addition of a source, that close on the kqueue
will never be called. The above code leaks sometimes due to a race
condition in inter-thread communications- bizarrely, it leaks
descriptor 4 which is the first that was allocated- I would have
thought that the last one would leak...
With the following hack-around code (based on yours), the fd leak is
permanently squelched:
#include <CoreFoundation/CoreFoundation.h>
#include <unistd.h>
#include <sys/event.h>
static void junkCallback(CFFileDescriptorRef fdref, CFOptionFlags
callBackTypes, void *info) {}
struct __FileDescriptorHackStruct
{
int junkA;
int junkB;
int junkC;
int internalKqueueDescriptor;
};
int main(int argc, char *argv[])
{
int i = 0;
for (i = 0; i < 3; i++)
{
CFFileDescriptorRef fileDescriptor = nil;
CFRunLoopSourceRef runLoopSource = nil;
fileDescriptor = CFFileDescriptorCreate(NULL, 0, false,
junkCallback, NULL);
runLoopSource = CFFileDescriptorCreateRunLoopSource(NULL,
fileDescriptor, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
runLoopSource, kCFRunLoopDefaultMode);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
runLoopSource, kCFRunLoopDefaultMode);
CFRelease(runLoopSource);
close(((struct __FileDescriptorHackStruct*)fileDescriptor)-
>internalKqueueDescriptor);
CFFileDescriptorInvalidate(fileDescriptor);
CFRelease(fileDescriptor);
}
sleep(-1);
return 0;
}
At least it is not leaking threads. Speaking of which, why does each
file descriptor need to be watched by a new thread? Not even
CFSocketManager is that dumb. In any case, this is looking so bad that
I will likely need to implement my own CFFileDescriptor replacement.
Cheers,
M
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)
iEYEARECAAYFAkqN328ACgkQqVAj6JpR7t4LUQCfamtzP0xV6GWEBNxpQRw6ZK+I
SuAAn3wouHd+LXixOKheQFJL3ccy2IuI
=iogu
-----END PGP SIGNATURE-----
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden