Skip to content

Commit

Permalink
Add explicit reply dispatch queue to XPCConnection so that it is not …
Browse files Browse the repository at this point in the history
…primarily dependent on dispatch_get_current_queue() (This is a partial solution to issue #1)
  • Loading branch information
Joerg Jacobsen committed Aug 29, 2013
1 parent 7e27eb6 commit 3cab2ef
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
24 changes: 20 additions & 4 deletions XPCKit/XPCConnection.h
Expand Up @@ -26,6 +26,7 @@
XPCEventHandler _eventHandler;
xpc_connection_t _connection;
dispatch_queue_t _dispatchQueue;
dispatch_queue_t _replyDispatchQueue;
}

- (id)initWithServiceName:(NSString *)serviceName;
Expand All @@ -36,6 +37,11 @@
@property (nonatomic, readonly) xpc_connection_t connection;
@property (nonatomic, assign) dispatch_queue_t dispatchQueue;

/**
* Reply and error handler will be submitted to this queue
*/
@property (nonatomic, assign) dispatch_queue_t replyDispatchQueue;

// connection properties
@property (nonatomic, readonly) NSString *connectionName;
@property (nonatomic, readonly) NSNumber *connectionEUID;
Expand All @@ -45,10 +51,20 @@

-(void)sendMessage:(XPCMessage *)message;

// Sends a message to the associated connection in the XPC service and invokes the reply handler
// on the dispatch queue of self once the associated connection sends a reply.
// Logs an error message to the console if the connection does not reply for whatever reasons.

/*!
* @abstract
* Sends a message to the associated connection in the XPC service and invokes the reply handler
* on the replyDispatchQueue of self once the associated connection sends a reply.
* Logs an error message to the console if the connection does not reply for whatever reasons.
*
* @discussion
* If replyDispatchQueue is nil then dispatch_get_current_queue() will be used for backward compatibility.
* Be aware that this behavior will be removed in a future release.
*
* @param replyHandler
* Reply handler to be queued on replyDispatchQueue of self after message was executed by XPC service
*/
-(void)sendMessage:(XPCMessage *)message withReply:(XPCReplyHandler)replyHandler;

// Sends a message to the associated connection in the XPC service and invokes the reply handler
Expand All @@ -59,7 +75,7 @@

// Sends a selector and a target and an optional object argument to the associated connection in the XPC service
// which will invoke the selector on the (copied) target with the optional (copied) argument. Invokes the
// return value handler on the dispatch queue of self with the (copied) return value and possibly
// return value handler on the reply dispatch queue of self with the (copied) return value and possibly
// a (copied) error object supplied.

-(void)sendSelector:(SEL)inSelector withTarget:(id)inTarget object:(id)inObject returnValueHandler:(XPCReturnValueHandler)inReturnHandler;
Expand Down
21 changes: 16 additions & 5 deletions XPCKit/XPCConnection.m
Expand Up @@ -29,7 +29,7 @@

@implementation XPCConnection

@synthesize eventHandler=_eventHandler, dispatchQueue=_dispatchQueue, connection=_connection;
@synthesize eventHandler=_eventHandler, dispatchQueue=_dispatchQueue, replyDispatchQueue=_replyDispatchQueue, connection=_connection;

- (id)initWithServiceName:(NSString *)serviceName{
xpc_connection_t connection = xpc_connection_create([serviceName cStringUsingEncoding:NSUTF8StringEncoding], NULL);
Expand Down Expand Up @@ -88,6 +88,17 @@ -(void)setDispatchQueue:(dispatch_queue_t)dispatchQueue{
xpc_connection_set_target_queue(self.connection, self.dispatchQueue);
}

-(void)setReplyDispatchQueue:(dispatch_queue_t)dispatchQueue{
if(dispatchQueue){
dispatch_retain(dispatchQueue);
}

if(_replyDispatchQueue){
dispatch_release(_replyDispatchQueue);
}
_replyDispatchQueue = dispatchQueue;
}

-(void)receiveConnection:(xpc_connection_t)connection
{
// __block XPCConnection *this = self;
Expand Down Expand Up @@ -172,14 +183,14 @@ -(void)sendMessage:(XPCMessage *)inMessage
// Need to tell message that we want a direct reply
[inMessage setNeedsDirectReply:YES];

dispatch_queue_t currentQueue = dispatch_get_current_queue();
dispatch_retain(currentQueue);
dispatch_queue_t replyQueue = self.replyDispatchQueue ? self.replyDispatchQueue : dispatch_get_current_queue();
dispatch_retain(replyQueue);

XPCReplyHandler replyHandler = [inReplyHandler copy];
XPCErrorHandler errorHandler = [inErrorHandler copy];

dispatch_async(self.dispatchQueue, ^{
xpc_connection_send_message_with_reply(_connection, inMessage.XPCDictionary, currentQueue, ^(xpc_object_t event){
xpc_connection_send_message_with_reply(_connection, inMessage.XPCDictionary, replyQueue, ^(xpc_object_t event){
xpc_type_t type = xpc_get_type(event);

if (type == XPC_TYPE_ERROR)
Expand Down Expand Up @@ -207,7 +218,7 @@ -(void)sendMessage:(XPCMessage *)inMessage

[replyHandler release];
[errorHandler release];
dispatch_release(currentQueue);
dispatch_release(replyQueue);
});
});
}
Expand Down

0 comments on commit 3cab2ef

Please sign in to comment.