Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding SyncProxy

  • Loading branch information...
commit 459ab97068ac8d9d29ae9b2daa5b2ea87e1d0ad2 1 parent c46d1d4
@stevedekorte authored
View
10 ActorKit.xcodeproj/project.pbxproj
@@ -15,6 +15,8 @@
AA2FB4A9141F5EB700E57E01 /* NSObject+Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = AA2FB4A7141F5EB700E57E01 /* NSObject+Actor.h */; settings = {ATTRIBUTES = (Public, ); }; };
AA2FB4AA141F5EB700E57E01 /* NSObject+Actor.m in Sources */ = {isa = PBXBuildFile; fileRef = AA2FB4A8141F5EB700E57E01 /* NSObject+Actor.m */; };
AA2FB4AC141FF34200E57E01 /* README.txt in Resources */ = {isa = PBXBuildFile; fileRef = AA2FB4AB141FF34200E57E01 /* README.txt */; };
+ AA300E071420649100A63289 /* SyncProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = AA300E051420649100A63289 /* SyncProxy.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ AA300E081420649100A63289 /* SyncProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = AA300E061420649100A63289 /* SyncProxy.m */; };
AA9A97881419785000A2994E /* NSThread+Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9A97861419785000A2994E /* NSThread+Actor.h */; settings = {ATTRIBUTES = (Public, ); }; };
AA9A97891419785000A2994E /* NSThread+Actor.m in Sources */ = {isa = PBXBuildFile; fileRef = AA9A97871419785000A2994E /* NSThread+Actor.m */; };
AABB5D99140E0C220020BA06 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABB5D98140E0C220020BA06 /* Cocoa.framework */; };
@@ -33,6 +35,8 @@
AA2FB4A7141F5EB700E57E01 /* NSObject+Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Actor.h"; sourceTree = "<group>"; };
AA2FB4A8141F5EB700E57E01 /* NSObject+Actor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Actor.m"; sourceTree = "<group>"; };
AA2FB4AB141FF34200E57E01 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.txt; sourceTree = SOURCE_ROOT; };
+ AA300E051420649100A63289 /* SyncProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncProxy.h; sourceTree = "<group>"; };
+ AA300E061420649100A63289 /* SyncProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncProxy.m; sourceTree = "<group>"; };
AA9A97861419785000A2994E /* NSThread+Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSThread+Actor.h"; sourceTree = "<group>"; };
AA9A97871419785000A2994E /* NSThread+Actor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSThread+Actor.m"; sourceTree = "<group>"; };
AABB5D95140E0C220020BA06 /* ActorKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ActorKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -114,6 +118,8 @@
AA2FB4A8141F5EB700E57E01 /* NSObject+Actor.m */,
AA9A97861419785000A2994E /* NSThread+Actor.h */,
AA9A97871419785000A2994E /* NSThread+Actor.m */,
+ AA300E051420649100A63289 /* SyncProxy.h */,
+ AA300E061420649100A63289 /* SyncProxy.m */,
AABB5D9F140E0C220020BA06 /* Supporting Files */,
);
path = ActorKit;
@@ -139,11 +145,12 @@
buildActionMask = 2147483647;
files = (
AA2726621411886500FE0A43 /* ActorKit.h in Headers */,
- AA9A97881419785000A2994E /* NSThread+Actor.h in Headers */,
AAD00991141F0ED200566C36 /* Mutex.h in Headers */,
AA2FB4A2141F533C00E57E01 /* ActorProxy.h in Headers */,
AA2FB4A4141F533C00E57E01 /* FutureProxy.h in Headers */,
AA2FB4A9141F5EB700E57E01 /* NSObject+Actor.h in Headers */,
+ AA9A97881419785000A2994E /* NSThread+Actor.h in Headers */,
+ AA300E071420649100A63289 /* SyncProxy.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -213,6 +220,7 @@
AA2FB4A3141F533C00E57E01 /* ActorProxy.m in Sources */,
AA2FB4A5141F533C00E57E01 /* FutureProxy.m in Sources */,
AA2FB4AA141F5EB700E57E01 /* NSObject+Actor.m in Sources */,
+ AA300E081420649100A63289 /* SyncProxy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
4 ActorKit/NSObject+Actor.h
@@ -7,9 +7,11 @@
//
#import "ActorProxy.h"
+#import "SyncProxy.h"
@interface NSObject (NSObject_Actor)
-- (ActorProxy *)asActor;
+- asActor;
+- asSynchronous;
@end
View
21 ActorKit/NSObject+Actor.m
@@ -11,9 +11,9 @@
@implementation NSObject (NSObject_Actor)
-static char *actorKey = "actor";
+static char *actorKey = "ActorProxy";
-- (ActorProxy *)asActor
+- asActor
{
ActorProxy *actor = objc_getAssociatedObject(self, actorKey);
@@ -24,8 +24,23 @@ - (ActorProxy *)asActor
objc_setAssociatedObject(self, actorKey, actor, OBJC_ASSOCIATION_ASSIGN);
}
- return actor;
+ return (id)actor;
}
+static char *synchoronousKey = "SyncProxy";
+
+- asSynchronous
+{
+ SyncProxy *sp = objc_getAssociatedObject(self, synchoronousKey);
+
+ if(!sp)
+ {
+ sp = [[[SyncProxy alloc] init] autorelease];
+ [sp setSyncProxyTarget:self];
+ objc_setAssociatedObject(self, synchoronousKey, sp, OBJC_ASSOCIATION_ASSIGN);
+ }
+
+ return (id)sp;
+}
@end
View
21 ActorKit/SyncProxy.h
@@ -0,0 +1,21 @@
+//
+// NSObject+Actor.h
+// ActorKit
+//
+// Created by Steve Dekorte on 20110831.
+// Copyright 2011 Steve Dekorte. BSD licensed.
+//
+// A simple proxy wrapper that synchronizes all messages to the target
+
+@interface SyncProxy : NSProxy
+{
+ id syncProxyTarget;
+ NSLock *syncProxyLock;
+}
+
+// all private
+
+@property (retain, atomic) id syncProxyTarget;
+@property (retain, atomic) NSLock *syncProxyLock;
+
+@end
View
52 ActorKit/SyncProxy.m
@@ -0,0 +1,52 @@
+//
+// NSObject+Actor.m
+// ActorKit
+//
+// Created by Steve Dekorte on 20110831.
+// Copyright 2011 Steve Dekorte. BSD licensed.
+//
+
+#import "SyncProxy.h"
+
+
+@implementation SyncProxy
+
+@synthesize syncProxyTarget;
+@synthesize syncProxyLock;
+
+- init
+{
+ //self = [super init]; // NSProxy doesn't implement init
+ [self setSyncProxyLock:[[[NSLock alloc] init] autorelease]];
+ //[[syncProxyLock setName:[syncProxyTarget description]];
+ return self;
+}
+
+- (void)dealloc
+{
+ [self setSyncProxyTarget:nil];
+ [self setSyncProxyLock:nil];
+ [super dealloc];
+}
+
+- (BOOL)respondsToSelector:(SEL)aSelector
+{
+ return [syncProxyTarget respondsToSelector:aSelector];
+}
+
+- (void)forwardInvocation:(NSInvocation *)anInvocation
+{
+ // probably could have used @synchronized() {}
+ // but access to the lock object might be useful later
+
+ [syncProxyLock lock];
+ [anInvocation invokeWithTarget:syncProxyTarget];
+ [syncProxyLock unlock];
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
+{
+ return [syncProxyTarget methodSignatureForSelector:aSelector];
+}
+
+@end
View
20 README.txt
@@ -64,6 +64,26 @@ Notes:
actor is returned for multiple calls of asActor on the same instance.
+
+SyncProxy
+
+ As an extra feature, NSObject is also extended to have a asSynchronous method.
+ Calling it will return a proxy to the object which will ensure that only one thread
+ can message the object at a time. This allows any Objective-C class to be used
+ in a thread safe way. This does no checks for deadlocks and may not be optimal
+ in performance, but it is an convenient way to get object level thread safety.
+
+
+Example:
+
+ // just call asSynchronous to get the proxy
+
+ NSMutableDictionary *dict = [[NSMutableDictionary dictionary] asSynchronous];
+
+ // now message sends from all threads to dict will be locked such that only one
+ // thread can access it at a time. Again, this does not use busy waits.
+
+
Credits:
Please sign in to comment.
Something went wrong with that request. Please try again.