-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSSYRunLoopTickler.m
44 lines (38 loc) · 1.38 KB
/
SSYRunLoopTickler.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#import "SSYRunLoopTickler.h"
@implementation SSYRunLoopTickler
+ (void)tickle {
NSPort* sendPort = [NSMachPort port] ;
[[NSRunLoop currentRunLoop] addPort:sendPort
forMode:NSDefaultRunLoopMode] ;
NSPort* receivePort = [NSMachPort port] ;
NSPortMessage* message = [[NSPortMessage alloc] initWithSendPort:sendPort
receivePort:receivePort
components:nil] ;
BOOL sentOk = [message sendBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]] ;
if (!sentOk) {
// Should actually return an NSError, but I don't think
// this will ever happen in real life, so I'm just going
// to log it.
NSLog(@"%s failed to send its message.", __PRETTY_FUNCTION__) ;
}
#if !__has_feature(objc_arc)
[message release] ;
#endif
// If I remove the port now, the desired "tickle" causing a
// blocked -[NSRunLoop runMode:beforeDate:] to return will
// not occur. But if I do so with a delay of 0.0, it works.
[self performSelector:@selector(removePort:)
withObject:sendPort
afterDelay:0.0] ;
}
/*!
Just a debugging note: If the +tickle message is sent from a
secondary thread which exits, the delayed performance of this
method will not occur, but that is OK because when its thread
ends the port will be "removed" anyhow.
*/
+ (void)removePort:(NSPort*)port {
[[NSRunLoop currentRunLoop] removePort:port
forMode:NSDefaultRunLoopMode] ;
}
@end