Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

asActor now always returns the same actor for a given instance

  • Loading branch information...
commit c46d1d4be9f1e3db8aaafb53ace7d6bb57bc3e9c 1 parent a848ec9
Steve Dekorte authored
BIN  .DS_Store
Binary file not shown
5,071 ActorKit.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/UserInterfaceState.xcuserstate
2,340 additions, 2,731 deletions not shown
3  ActorKit/ActorProxy.h
@@ -20,10 +20,11 @@
NSThread *actorThread;
+// all private
@property (retain, atomic) id actorTarget;
@property (retain, atomic) Mutex *actorMutex;
@property (retain, atomic) FutureProxy *firstFuture;
@property (retain, atomic) NSThread *actorThread;
16 ActorKit/FutureProxy.h
@@ -18,18 +18,18 @@
BOOL done;
NSMutableSet *futureWaitingThreads;
NSException *futureException;
- Mutex *futureLock;
+ Mutex *futureLock; // used to pause any threads accessing future before it is done
// these are all private
-@property (assign, nonatomic) id futureActor;
-@property (retain, nonatomic) NSInvocation *futureInvocation;
-@property (retain, nonatomic) id futureValue;
-@property (retain, nonatomic) id nextFuture;
-@property (retain, nonatomic) NSMutableSet *futureWaitingThreads;
-@property (retain, nonatomic) NSException *futureException;
-@property (retain, nonatomic) Mutex *futureLock;
+@property (assign, atomic) id futureActor;
+@property (retain, atomic) NSInvocation *futureInvocation;
+@property (retain, atomic) id futureValue;
+@property (retain, atomic) id nextFuture;
+@property (retain, atomic) NSMutableSet *futureWaitingThreads;
+@property (retain, atomic) NSException *futureException;
+@property (retain, atomic) Mutex *futureLock;
- (void)futureAppend:(FutureProxy *)aFuture;
- (void)futureSend;
1  ActorKit/FutureProxy.m
@@ -140,7 +140,6 @@ - (void)futureRaiseExceptionIfDeadlock
[NSException raise:@"Future" format:@"waiting for result on this coroutine would cause a deadlock"];
- futureResult
17 ActorKit/NSObject+Actor.m
@@ -7,15 +7,24 @@
#import "NSObject+Actor.h"
-//#import <objc/runtime.h>
+#import <objc/runtime.h>
@implementation NSObject (NSObject_Actor)
+static char *actorKey = "actor";
- (ActorProxy *)asActor
- ActorProxy *ap = [[[ActorProxy alloc] init] autorelease];
- [ap setActorTarget:self];
- return ap;
+ ActorProxy *actor = objc_getAssociatedObject(self, actorKey);
+ if(!actor)
+ {
+ actor = [[[ActorProxy alloc] init] autorelease];
+ [actor setActorTarget:self];
+ objc_setAssociatedObject(self, actorKey, actor, OBJC_ASSOCIATION_ASSIGN);
+ }
+ return actor;
2  ActorKit/NSThread+Actor.m
@@ -48,7 +48,7 @@ - (Mutex *)lock
Mutex *lock = [[self threadDictionary] objectForKey:@"lock"];
- if (!lock)
+ if (lock == nil)
lock = [[[NSLock alloc] init] autorelease];
[self setLock:lock];
30 README.txt
@@ -1,27 +1,36 @@
- ActorKit allows any object to become an actor.
+ ActorKit is a framework supporting multithreaded actors with transparent futures in Objective-C.
- Each actor has an os thread and a queue of incoming messages which it processes in
- first-in-first-out order.
+ Sending an "asActor" message to any object returns an actor proxy for the object.
- Any message to an actor returns a "future" object which is a proxy for the result
- and only blocks when it is accessed if the result isn't ready.
+ Each actor spawns an os thread to process it's queue of messages.
+ Sending messages to the actor will queue them to be processed in first-in-first-out order
+ by the actor's thread and immediately returns a "future" object.
- Futures detect and raise an exception in situations that would cause a deadlock.
+ A future is a proxy for the result. If it is accessed before the result is ready, it
+ pauses any calling threads until it is ready. After it is ready, it acts as a transparent
+ proxy for the result, passing messages to the result as if the future were the same object.
+ Futures detect and raise an exception in situations where pausing the calling thread
+ would cause a deadlock.
// these spawn threads for each actor to and return immediately
NSData *future1 = [(NSURL *)[[NSURL URLWithString:@""] asActor] fetch];
NSData *future2 = [(NSURL *)[[NSURL URLWithString:@""] asActor] fetch];
+ // ... do stuff that doesn't need to wait on the results ...
// now when we try to access the values, they block if the values aren't ready
NSLog(@"request 1 returned %i bytes", (int)[future1 length]);
NSLog(@"request 2 returned %i bytes", (int)[future2 length]);
@@ -51,11 +60,14 @@ Notes:
When an actor finishes processing it's message queue, it's thread
is paused until a new message is added to the queue.
+ Objects store their actor proxies as an associated object so the same
+ actor is returned for multiple calls of asActor on the same instance.
- Thanks to Mark Papadakis for help with figuring out how to properly use mutex conditions.
+ Thanks to Mark Papadakis for help me figure out how to properly use mutex conditions.
Please sign in to comment.
Something went wrong with that request. Please try again.