Skip to content

Commit 4611071

Browse files
committed
fix crash calling nonexistent delegate (also memory leak)
1 parent a0bb2b6 commit 4611071

2 files changed

Lines changed: 19 additions & 6 deletions

File tree

VDKQueue.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
//
3030
// VDKQueue is also simplified. The option to use it as a singleton is removed. You simply alloc/init an instance and add paths you want to
3131
// watch. Your objects can be alerted to changes either by notifications or by a delegate method (or both). See below.
32+
// When you're done with the object, call stopWatching (to release the background thread), then release.
3233
//
3334
// It also fixes several bugs. For one, it won't crash if it can't create a file descriptor to a file you ask it to watch. (By default, an OS X process can only
3435
// have about 3,000 file descriptors open at once. If you hit that limit, UKKQueue will crash. VDKQueue will not.)
@@ -139,6 +140,7 @@ extern NSString * VDKQueueAccessRevocationNotification;
139140
- (void) removePath:(NSString *)aPath;
140141
- (void) removeAllPaths;
141142

143+
- (void) stopWatching; // You must call this when you release the VDKQueue object
142144

143145
- (NSUInteger) numberOfWatchedPaths; // Returns the number of paths that this VDKQueue instance is actively watching.
144146

VDKQueue.m

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,6 @@ - (id) init
141141

142142
- (void) dealloc
143143
{
144-
// Shut down the thread that's scanning for kQueue events
145-
_keepWatcherThreadRunning = NO;
146-
147-
// Do this to close all the open file descriptors for files we're watching
148-
[self removeAllPaths];
149-
150144
[_watchedPathEntries release];
151145
_watchedPathEntries = nil;
152146

@@ -422,6 +416,23 @@ - (void) removeAllPaths
422416
}
423417

424418

419+
- (void) stopWatching
420+
{
421+
// This method must be called if we want this object to ever be dealloc'd. This is because detachNewThreadSelector:toTarget:withObject:
422+
// retains the target (in this case, self), setting the retainCount to 2. Aside from the memory leak issue, if the thread is never terminated,
423+
// the watcher thread might still try to send messages to a nonexistent delegate, causing your app to crash.
424+
@synchronized(self)
425+
{
426+
// Shut down the thread that's scanning for kQueue events
427+
_keepWatcherThreadRunning = NO;
428+
429+
// Do this to close all the open file descriptors for files we're watching
430+
[_pathMap removeAllObjects];
431+
[_watchedPathEntries removeAllObjects];
432+
}
433+
}
434+
435+
425436
- (NSUInteger) numberOfWatchedPaths
426437
{
427438
NSUInteger count;

0 commit comments

Comments
 (0)