aboutsummaryrefslogtreecommitdiff
path: root/Foundation
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2010-04-15 17:31:09 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2010-04-15 17:31:09 +0000
commit2ddb245fac99802e63742c21f7da0d499e9cecf6 (patch)
tree3eebbf1aeed8269c8b14de81e8b680e784b8709b /Foundation
parent30ac0ff87b594d7bca3a5cc2789ca415840ea0b1 (diff)
[Author: dmaclach]
refactor GTMUnitTestingUtilities into GTMAppKitUnitTestingUtilties and GTMFoundationUnitTestingUtilities. convert GTMSignalHandler over to using new runloop routines fix bug in GTMSignalHandler API with GC where releasing it wasn't sufficient to stop it listening. R=thomasvl DELTA=1227 (638 added, 566 deleted, 23 changed)
Diffstat (limited to 'Foundation')
-rw-r--r--Foundation/GTMSignalHandler.h3
-rw-r--r--Foundation/GTMSignalHandler.m18
-rw-r--r--Foundation/GTMSignalHandlerTest.m52
3 files changed, 45 insertions, 28 deletions
diff --git a/Foundation/GTMSignalHandler.h b/Foundation/GTMSignalHandler.h
index b1c7c2f..6297197 100644
--- a/Foundation/GTMSignalHandler.h
+++ b/Foundation/GTMSignalHandler.h
@@ -70,4 +70,7 @@
target:(id)target
action:(SEL)action;
+// Invalidates the handler so that it isn't listening anymore.
+- (void)invalidate;
+
@end
diff --git a/Foundation/GTMSignalHandler.m b/Foundation/GTMSignalHandler.m
index dd67269..677c10a 100644
--- a/Foundation/GTMSignalHandler.m
+++ b/Foundation/GTMSignalHandler.m
@@ -44,7 +44,6 @@ static CFSocketRef gRunLoopSocket = NULL;
- (void)notify;
- (void)addFileDescriptorMonitor:(int)fd;
- (void)registerWithKQueue;
-- (void)unregisterWithKQueue;
@end
@@ -88,19 +87,17 @@ static CFSocketRef gRunLoopSocket = NULL;
}
#if GTM_SUPPORT_GC
+
- (void)finalize {
- [self unregisterWithKQueue];
-
+ [self invalidate];
[super finalize];
-
}
+
#endif
- (void)dealloc {
- [self unregisterWithKQueue];
-
+ [self invalidate];
[super dealloc];
-
}
// Cribbed from Advanced Mac OS X Programming.
@@ -181,7 +178,7 @@ static void SocketCallBack(CFSocketRef socketref, CFSocketCallBackType type,
}
-- (void)unregisterWithKQueue {
+- (void)invalidate {
// Short-circuit cases where we didn't actually register a kqueue event.
if (signo_ == 0) return;
if (action_ == nil) return;
@@ -193,7 +190,10 @@ static void SocketCallBack(CFSocketRef socketref, CFSocketCallBackType type,
if (kevent(gSignalKQueueFileDescriptor, &filter, 1, NULL, 0, &noWait) != 0) {
_GTMDevLog(@"could not remove event for signal %d. Errno %d", signo_, errno); // COV_NF_LINE
}
-
+
+ // Set action_ to nil so that if invalidate is called on us twice,
+ // nothing happens.
+ action_ = nil;
}
- (void)notify {
diff --git a/Foundation/GTMSignalHandlerTest.m b/Foundation/GTMSignalHandlerTest.m
index a0019f3..191d67f 100644
--- a/Foundation/GTMSignalHandlerTest.m
+++ b/Foundation/GTMSignalHandlerTest.m
@@ -19,19 +19,22 @@
#import "GTMSenTestCase.h"
#import "GTMSignalHandler.h"
#import "GTMUnitTestDevLog.h"
+#import "GTMFoundationUnitTestingUtilities.h"
@interface GTMSignalHandlerTest : GTMTestCase
@end
-@interface SignalCounter : NSObject {
+@interface SignalCounter : NSObject<GTMUnitTestingRunLoopContext> {
@public
int signalCount_;
int lastSeenSignal_;
+ BOOL shouldStop_;
}
- (int)count;
- (int)lastSeen;
- (void)countSignal:(int)signo;
+ (id)signalCounter;
+- (void)resetShouldStop;
@end // SignalCounter
@implementation SignalCounter
@@ -48,17 +51,21 @@
- (void)countSignal:(int)signo {
signalCount_++;
lastSeenSignal_ = signo;
+ shouldStop_ = YES;
}
-@end
-@implementation GTMSignalHandlerTest
+- (BOOL)shouldStop {
+ return shouldStop_;
+}
-// Spin the run loop so that the kqueue event notifications will get delivered.
-- (void)giveSomeLove {
- NSDate *endTime = [NSDate dateWithTimeIntervalSinceNow:0.5];
- [[NSRunLoop currentRunLoop] runUntilDate:endTime];
+- (void)resetShouldStop {
+ shouldStop_ = NO;
}
+@end
+
+@implementation GTMSignalHandlerTest
+
- (void)testNillage {
GTMSignalHandler *handler;
@@ -81,23 +88,28 @@
SignalCounter *counter = [SignalCounter signalCounter];
STAssertNotNil(counter, nil);
- GTMSignalHandler *handler = [[GTMSignalHandler alloc]
- initWithSignal:SIGWINCH
- target:counter
- action:@selector(countSignal:)];
+ GTMSignalHandler *handler = [[[GTMSignalHandler alloc]
+ initWithSignal:SIGWINCH
+ target:counter
+ action:@selector(countSignal:)]
+ autorelease];
STAssertNotNil(handler, nil);
raise(SIGWINCH);
- [self giveSomeLove];
+
+ NSRunLoop *rl = [NSRunLoop currentRunLoop];
+ [rl gtm_runUpToSixtySecondsWithContext:counter];
STAssertEquals([counter count], 1, nil);
STAssertEquals([counter lastSeen], SIGWINCH, nil);
-
+ [counter resetShouldStop];
+
raise(SIGWINCH);
- [self giveSomeLove];
+ [rl gtm_runUpToSixtySecondsWithContext:counter];
STAssertEquals([counter count], 2, nil);
STAssertEquals([counter lastSeen], SIGWINCH, nil);
-
+ [counter resetShouldStop];
+
// create a second one to make sure we're seding data where we want
SignalCounter *counter2 = [SignalCounter signalCounter];
STAssertNotNil(counter2, nil);
@@ -106,19 +118,20 @@
action:@selector(countSignal:)] autorelease];
raise(SIGUSR1);
- [self giveSomeLove];
+ [rl gtm_runUpToSixtySecondsWithContext:counter2];
STAssertEquals([counter count], 2, nil);
STAssertEquals([counter lastSeen], SIGWINCH, nil);
STAssertEquals([counter2 count], 1, nil);
STAssertEquals([counter2 lastSeen], SIGUSR1, nil);
- [handler release];
+ [handler invalidate];
// The signal is still ignored (so we shouldn't die), but the
// the handler method should not get called.
raise(SIGWINCH);
-
+ [rl runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.2]];
+
STAssertEquals([counter count], 2, nil);
STAssertEquals([counter lastSeen], SIGWINCH, nil);
STAssertEquals([counter2 count], 1, nil);
@@ -135,7 +148,8 @@
action:NULL] autorelease];
raise(SIGUSR1);
- [self giveSomeLove];
+ NSRunLoop *rl = [NSRunLoop currentRunLoop];
+ [rl runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.2]];
STAssertEquals([counter count], 0, nil);
}