Browse files

ZMQContext locks around sockets array mutations.

  • Loading branch information...
1 parent 28b2140 commit 76a1a048736839d2cfcb3462f99016eb94b57882 @jeremy-w committed Jul 3, 2010
Showing with 56 additions and 1 deletion.
  1. +50 −0 README.mkd
  2. +2 −0 src/ZMQContext.h
  3. +4 −1 src/ZMQContext.m
50 README.mkd
@@ -10,3 +10,53 @@ laid out by the official
[zmq-docs]: (zmq(7) Manual Page)
[binding-zmq]: (Guidelines for ZeroMQ Bindings)
+Refer to the [ZeroMQ manual pages][zmq-docs].
+The Objective-C binding
+maintains a bit more state
+than the C API exposes,
+in that you can query
+a `ZMQContext`
+for its sockets
+and query a `ZMQSocket`
+for its context.
+Thread Safety
+ZeroMQ has some restrictive thread safety and coupling issues:
+* Sockets can only be used from the thread that created them.
+* All ZMQ sockets provided in a single call to `zmq_poll()` must have been created using the same context.
+Because sockets
+are coupled to contexts
+for polling,
+you have to track
+each socket's context
+and make sure not to mix them.
+(The `ZMQSocket` class tracks this for you.)
+Because each socket
+is bound to the thread that created it,
+you must be very careful when using
+ZeroMQ sockets
+with Grand Central Dispatch
+or `NSOperationQueue`.
+The only persistent thread
+that these two expose
+is the thread
+you're least likely
+to want to perform socket operations on:
+the main thread.
+To Do
+* Add functional tests in the form of sample code.
+* Provide a more (Core)Foundation-like API
+(CFSocket, CFFileDescriptor)
+that takes advantage of the runloop.
+This is complicated by
+the threading constraints
+present in libzmq-2.0.7.
2 src/ZMQContext.h
@@ -1,9 +1,11 @@
#import <Foundation/Foundation.h>
#import "ZMQSocket.h" // ZMQSocketType
+#import <libkern/OSAtomic.h>
@interface ZMQContext : NSObject {
void *context;
NSMutableArray *sockets;
+ OSSpinLock socketsLock;
BOOL terminated;
+ (void)getZMQVersionMajor:(int *)major minor:(int *)minor patch:(int *)patch;
5 src/ZMQContext.m
@@ -27,6 +27,7 @@ - (id)initWithIOThreads:(NSUInteger)threadCount {
return nil;
+ socketsLock = OS_SPINLOCK_INIT;
sockets = [[NSMutableArray alloc] init];
return self;
@@ -44,7 +45,9 @@ - (ZMQSocket *)socketWithType:(ZMQSocketType)type {
ZMQSocket *
socket = [[[ZMQSocket alloc] initWithContext:self type:type] autorelease];
if (socket) {
- [(NSMutableArray *)self.sockets addObject:socket];
+ OSSpinLockLock(&socketsLock); {
+ [(NSMutableArray *)self.sockets addObject:socket];
+ } OSSpinLockUnlock(&socketsLock);
return socket;

0 comments on commit 76a1a04

Please sign in to comment.