Skip to content

Commit d5f40d9

Browse files
bastilimbach1c3t3a
authored andcommitted
fix: deadlock on recursive emit_with_ack calls
1 parent 2ef32ec commit d5f40d9

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

socketio/src/client/raw_client.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,18 @@ impl RawClient {
277277
return Ok(());
278278
};
279279

280-
self.outstanding_acks.lock()?.retain_mut(|ack| {
281-
if ack.id != id {
282-
return true;
283-
}
280+
let outstanding_ack = {
281+
let mut outstanding_acks = self.outstanding_acks.lock()?;
282+
outstanding_acks
283+
.iter()
284+
.position(|ack| ack.id == id)
285+
.map(|pos| outstanding_acks.remove(pos))
286+
};
284287

288+
// If we found a matching ack, call its callback otherwise ignore it.
289+
// The official implementation just removes the ack id on timeout:
290+
// https://github.com/socketio/socket.io-client/blob/main/lib/socket.ts#L467-L495
291+
if let Some(mut ack) = outstanding_ack {
285292
if ack.time_started.elapsed() < ack.timeout {
286293
if let Some(ref payload) = socket_packet.data {
287294
ack.callback.deref_mut()(Payload::from(payload.to_owned()), self.clone());
@@ -293,10 +300,7 @@ impl RawClient {
293300
}
294301
}
295302
}
296-
// nope, just ignore it, the official implment just remove the ack id when timeout
297-
// https://github.com/socketio/socket.io-client/blob/main/lib/socket.ts#L467-L495
298-
false
299-
});
303+
}
300304

301305
Ok(())
302306
}

0 commit comments

Comments
 (0)