From 4c4ce6e5388e733741ff830419452e4a15bf31fa Mon Sep 17 00:00:00 2001 From: "gtm.daemon" Date: Wed, 14 Nov 2012 19:30:11 +0000 Subject: [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) --- Foundation/GTMNSThread+Blocks.h | 11 +++++++++++ Foundation/GTMNSThread+Blocks.m | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) (limited to 'Foundation') 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 + #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 -- cgit v1.2.3