diff --git a/SocketIO-MacTests/SocketObjectiveCTest.m b/SocketIO-MacTests/SocketObjectiveCTest.m index 6043a24..2270a42 100644 --- a/SocketIO-MacTests/SocketObjectiveCTest.m +++ b/SocketIO-MacTests/SocketObjectiveCTest.m @@ -21,7 +21,8 @@ - (void)setUp { [super setUp]; NSURL* url = [[NSURL alloc] initWithString:@"http://localhost"]; - self.socket = [[SocketIOClient alloc] initWithSocketURL:url options:nil]; + self.socket = [[SocketIOClient alloc] initWithSocketURL:url + options:@{@"handleQueue": dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL)}]; } - (void)testOnSyntax { diff --git a/SocketIO-MacTests/SocketSideEffectTest.swift b/SocketIO-MacTests/SocketSideEffectTest.swift index 7f4bba6..2e377c5 100644 --- a/SocketIO-MacTests/SocketSideEffectTest.swift +++ b/SocketIO-MacTests/SocketSideEffectTest.swift @@ -16,7 +16,8 @@ class SocketSideEffectTest: XCTestCase { override func setUp() { super.setUp() - socket = SocketIOClient(socketURL: URL(string: "http://localhost/")!) + socket = SocketIOClient(socketURL: URL(string: "http://localhost/")!, + options: [.handleQueue(DispatchQueue(label: "handleQueue", attributes: .serial, target: nil))]) socket.setTestable() } diff --git a/Source/SocketAckManager.swift b/Source/SocketAckManager.swift index b7c050a..cda532f 100644 --- a/Source/SocketAckManager.swift +++ b/Source/SocketAckManager.swift @@ -56,19 +56,17 @@ struct SocketAckManager { acks.insert(SocketAck(ack: ack, callback: callback)) } + /// Should be called on handle queue mutating func executeAck(_ ack: Int, items: [AnyObject]) { let callback = acks.remove(SocketAck(ack: ack)) - - DispatchQueue.main.async { - callback?.callback(items) - } + + callback?.callback(items) } + /// Should be called on handle queue mutating func timeoutAck(_ ack: Int) { let callback = acks.remove(SocketAck(ack: ack)) - DispatchQueue.main.async { - callback?.callback(["NO ACK"]) - } + callback?.callback(["NO ACK"]) } } diff --git a/Source/SocketIOClient.swift b/Source/SocketIOClient.swift index 793af06..4beda6b 100644 --- a/Source/SocketIOClient.swift +++ b/Source/SocketIOClient.swift @@ -60,6 +60,7 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable private var reconnecting = false private(set) var currentAck = -1 + // Handle queue also controls access to ackManager private(set) var handleQueue = DispatchQueue.main private(set) var reconnectAttempts = -1 @@ -162,7 +163,10 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable return {[weak self, ack = currentAck] timeout, callback in if let this = self { - this.ackHandlers.addAck(ack, callback: callback) + this.handleQueue.sync() { + this.ackHandlers.addAck(ack, callback: callback) + } + this._emit(items, ack: ack) if timeout != 0 { @@ -294,7 +298,9 @@ public final class SocketIOClient : NSObject, SocketEngineClient, SocketParsable DefaultSocketLogger.Logger.log("Handling ack: %@ with data: %@", type: logType, args: ack, data) - ackHandlers.executeAck(ack, items: data) + handleQueue.async() { + self.ackHandlers.executeAck(ack, items: data) + } } /// Causes an event to be handled. Only use if you know what you're doing.