aboutsummaryrefslogtreecommitdiff
path: root/Foundation
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2012-11-14 19:30:11 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2012-11-14 19:30:11 +0000
commit4c4ce6e5388e733741ff830419452e4a15bf31fa (patch)
tree71858b4610f3779b858cd5d68c2434c961b91436 /Foundation
parentd1623bbd42d3c4057d12dcec6297b63f27d4300e (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.h11
-rw-r--r--Foundation/GTMNSThread+Blocks.m41
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