diff options
author | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2012-11-14 19:30:11 +0000 |
---|---|---|
committer | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2012-11-14 19:30:11 +0000 |
commit | 4c4ce6e5388e733741ff830419452e4a15bf31fa (patch) | |
tree | 71858b4610f3779b858cd5d68c2434c961b91436 /Foundation | |
parent | d1623bbd42d3c4057d12dcec6297b63f27d4300e (diff) |
[Author: dmaclach]
Add GTMSimpleWorkerThread for easily creating a thread that just handles blocks and performSelector calls.
R=thomasvl
DELTA=52 (52 added, 0 deleted, 0 changed)
Diffstat (limited to 'Foundation')
-rw-r--r-- | Foundation/GTMNSThread+Blocks.h | 11 | ||||
-rw-r--r-- | Foundation/GTMNSThread+Blocks.m | 41 |
2 files changed, 52 insertions, 0 deletions
diff --git a/Foundation/GTMNSThread+Blocks.h b/Foundation/GTMNSThread+Blocks.h index 755f1ce..4d92b31 100644 --- a/Foundation/GTMNSThread+Blocks.h +++ b/Foundation/GTMNSThread+Blocks.h @@ -36,3 +36,14 @@ @end #endif // NS_BLOCKS_AVAILABLE + +// A simple thread that does nothing but handle performBlock and +// performSelector calls. +@interface GTMSimpleWorkerThread : NSThread { + @private + CFRunLoopRef runLoop_; +} + +// Will stop the thread. +- (void)stop; +@end diff --git a/Foundation/GTMNSThread+Blocks.m b/Foundation/GTMNSThread+Blocks.m index 70ee5b6..6757363 100644 --- a/Foundation/GTMNSThread+Blocks.m +++ b/Foundation/GTMNSThread+Blocks.m @@ -18,6 +18,8 @@ #import "GTMNSThread+Blocks.h" +#include <pthread.h> + #if NS_BLOCKS_AVAILABLE @implementation NSThread (GTMBlocksAdditions) @@ -49,3 +51,42 @@ @end #endif // NS_BLOCKS_AVAILABLE + +@implementation GTMSimpleWorkerThread + +- (void)main { + [self setThreadDebuggerName:[self name]]; + + // Add a port to the runloop so that it stays alive. Without a port attached + // to it, a runloop will immediately return when you call run on it. + NSPort *tempPort = [NSPort port]; + NSRunLoop *loop = [NSRunLoop currentRunLoop]; + [loop addPort:tempPort forMode:NSDefaultRunLoopMode]; + + // Run the loop using CFRunLoopRun because [NSRunLoop run] will sometimes nest + // runloops making it impossible to stop. + runLoop_ = [loop getCFRunLoop]; + CFRunLoopRun(); +} + +- (void)setThreadDebuggerName:(NSString *)name { + // [NSThread setName:] doesn't actually set the name in such a way that the + // debugger can see it. So we handle it here instead. + pthread_setname_np([name UTF8String]); +} + +- (void)stop { + CFRunLoopStop(runLoop_); +} + +- (void)setName:(NSString *)name { + if ([self isExecuting]) { + [self performSelector:@selector(setThreadDebuggerName:) + onThread:self + withObject:name + waitUntilDone:YES]; + } + [super setName:name]; +} + +@end |