From 55084d34b844b0cd04c5514d413f34df290d806e Mon Sep 17 00:00:00 2001 From: Viktor Kuzmin Date: Tue, 17 Dec 2024 23:30:28 +0200 Subject: [PATCH] Fix crash after concurent modification of acks Set. OnAckCallback.timingOut is called on user thread to finally perform emit. If user thread differs from handleQueue thread then it may lead to concurrent modification of acks Set. --- Source/SocketIO/Ack/SocketAckEmitter.swift | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Source/SocketIO/Ack/SocketAckEmitter.swift b/Source/SocketIO/Ack/SocketAckEmitter.swift index 18bebcfc..d7a6a46d 100644 --- a/Source/SocketIO/Ack/SocketAckEmitter.swift +++ b/Source/SocketIO/Ack/SocketAckEmitter.swift @@ -131,15 +131,17 @@ public final class OnAckCallback: NSObject { public func timingOut(after seconds: Double, callback: @escaping AckCallback) { guard let socket = self.socket, ackNumber != -1 else { return } - socket.ackHandlers.addAck(ackNumber, callback: callback) - socket.emit(items, ack: ackNumber, binary: binary) + socket.manager?.handleQueue.async { + socket.ackHandlers.addAck(self.ackNumber, callback: callback) + socket.emit(self.items, ack: self.ackNumber, binary: self.binary) - guard seconds != 0 else { return } + guard seconds != 0 else { return } - socket.manager?.handleQueue.asyncAfter(deadline: DispatchTime.now() + seconds) {[weak socket] in - guard let socket = socket else { return } + socket.manager?.handleQueue.asyncAfter(deadline: DispatchTime.now() + seconds) {[weak socket] in + guard let socket = socket else { return } - socket.ackHandlers.timeoutAck(self.ackNumber) + socket.ackHandlers.timeoutAck(self.ackNumber) + } } }