aboutsummaryrefslogtreecommitdiff
path: root/Foundation/GTMSignalHandler.m
diff options
context:
space:
mode:
authorGravatar thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2008-12-12 15:21:59 +0000
committerGravatar thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2008-12-12 15:21:59 +0000
commit9f64d056dd70f2f938ac6f5adb8e75b650dc2e1a (patch)
tree53de46b5785c60c1b5d6117e7696fec5d269690c /Foundation/GTMSignalHandler.m
parent1c129cbe26b539a4d7e0e47d90e84abcc71067bf (diff)
- fix up some style things.
- change the api slightly so things are a little more "cocoa-y".
Diffstat (limited to 'Foundation/GTMSignalHandler.m')
-rw-r--r--Foundation/GTMSignalHandler.m72
1 files changed, 32 insertions, 40 deletions
diff --git a/Foundation/GTMSignalHandler.m b/Foundation/GTMSignalHandler.m
index f88adf6..edfff7d 100644
--- a/Foundation/GTMSignalHandler.m
+++ b/Foundation/GTMSignalHandler.m
@@ -32,43 +32,33 @@
// File descriptor for the kqueue that will hold all of our signal events.
-static int gSignalKQueueFileDescriptor;
+static int gSignalKQueueFileDescriptor = 0;
// A wrapper around the kqueue file descriptor so we can put it into a
// runloop.
-static CFSocketRef gRunLoopSocket;
+static CFSocketRef gRunLoopSocket = NULL;
@interface GTMSignalHandler (PrivateMethods)
-
-// Invoke |handler_| on the |target_|, passing a boxed |signo_|.
- (void)notify;
-
-// Wrap the file descriptor in a CFSocket and add it to the runloop so that a
-// callback function will be called when there's activity on the descriptor. In
-// this case, we're interested in new stuff from the kqueue.
- (void)addFileDescriptorMonitor:(int)fd;
-
-// Add ourselves to our global kqueue.
- (void)registerWithKQueue;
-
-// Remove ourseves from our global kqueue.
- (void)unregisterWithKQueue;
-
-@end // PrivateMethods
+@end
@implementation GTMSignalHandler
-(id)init {
// Folks shouldn't call init directly, so they get what they deserve.
- return [self initWithSignal:0 target:nil handler:NULL];
-} // init
-
+ _GTMDevLog(@"Don't call init, use "
+ @"initWithSignal:target:action:");
+ return [self initWithSignal:0 target:nil action:NULL];
+}
- (id)initWithSignal:(int)signo
target:(id)target
- handler:(SEL)handler {
+ action:(SEL)action {
if ((self = [super init])) {
@@ -79,37 +69,36 @@ static CFSocketRef gRunLoopSocket;
signo_ = signo;
target_ = target; // Don't retain since target will most likely retain us.
- handler_ = handler;
+ action_ = action;
GTMAssertSelectorNilOrImplementedWithArguments(target_,
- handler_,
- @encode(NSNumber *),
+ action_,
+ @encode(int),
NULL);
// We're handling this signal via kqueue, so turn off the usual signal
// handling.
signal(signo_, SIG_IGN);
- if (handler != NULL) {
+ if (action != NULL) {
[self registerWithKQueue];
}
}
return self;
-} // initWithSignal
+}
- (void)finalize {
[self unregisterWithKQueue];
[super finalize];
-} // finalize
+}
- (void)dealloc {
[self unregisterWithKQueue];
[super dealloc];
-} // dealloc
-
+}
// Cribbed from Advanced Mac OS X Programming.
static void SocketCallBack(CFSocketRef socketref, CFSocketCallBackType type,
@@ -123,8 +112,7 @@ static void SocketCallBack(CFSocketRef socketref, CFSocketCallBackType type,
[handler notify];
}
-} // SocketCallBack
-
+}
// Cribbed from Advanced Mac OS X Programming
- (void)addFileDescriptorMonitor:(int)fd {
@@ -154,8 +142,7 @@ static void SocketCallBack(CFSocketRef socketref, CFSocketCallBackType type,
bailout:
return;
-} // addFileDescriptorMonitor
-
+}
- (void)registerWithKQueue {
@@ -182,13 +169,12 @@ static void SocketCallBack(CFSocketRef socketref, CFSocketCallBackType type,
_GTMDevLog(@"could not add event for signal %d. Errno %d", signo_, errno); // COV_NF_LINE
}
-} // registerWithKQueue
-
+}
- (void)unregisterWithKQueue {
// Short-circuit cases where we didn't actually register a kqueue event.
if (signo_ == 0) return;
- if (handler_ == 0) return;
+ if (action_ == nil) return;
struct kevent filter;
EV_SET(&filter, signo_, EVFILT_SIGNAL, EV_DELETE, 0, 0, self);
@@ -198,12 +184,18 @@ static void SocketCallBack(CFSocketRef socketref, CFSocketCallBackType type,
_GTMDevLog(@"could not remove event for signal %d. Errno %d", signo_, errno); // COV_NF_LINE
}
-} // unregisterWithKQueue
-
+}
- (void)notify {
- [target_ performSelector:handler_
- withObject:[NSNumber numberWithInt:signo_]];
-} // notify
-
-@end // GTMSignalHandler
+ // Now, fire the selector
+ NSMethodSignature *methodSig = [target_ methodSignatureForSelector:action_];
+ _GTMDevAssert(methodSig != nil, @"failed to get the signature?");
+ NSInvocation *invocation
+ = [NSInvocation invocationWithMethodSignature:methodSig];
+ [invocation setTarget:target_];
+ [invocation setSelector:action_];
+ [invocation setArgument:&signo_ atIndex:2];
+ [invocation invoke];
+}
+
+@end