From 7447d95f1bd309a1a25cee01d527f2f3a92766ba Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Thu, 8 Jun 2023 01:51:45 +0200 Subject: [PATCH] webrtc/signalling: fix race condition in message ordering Spawning one task per message to send out instead of sending them out sequentially from the one task used to poll the handler sometimes resulted in peers receiving ICE candidates before SDP offers, triggering hard to understand errors in the browser. Part-of: --- net/webrtc/signalling/src/server/mod.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/net/webrtc/signalling/src/server/mod.rs b/net/webrtc/signalling/src/server/mod.rs index e6ff1162..0510437c 100644 --- a/net/webrtc/signalling/src/server/mod.rs +++ b/net/webrtc/signalling/src/server/mod.rs @@ -38,7 +38,7 @@ impl Server { #[instrument(level = "debug", skip(factory))] pub fn spawn< I: for<'a> Deserialize<'a>, - O: Serialize + std::fmt::Debug, + O: Serialize + std::fmt::Debug + Send + Sync, Factory: FnOnce(Pin)> + Send>>) -> St, St: Stream, >( @@ -72,12 +72,19 @@ impl Server { task::spawn(async move { while let Some((peer_id, msg)) = handler.next().await { match serde_json::to_string(&msg) { - Ok(msg) => { - if let Some(peer) = state_clone.lock().unwrap().peers.get_mut(&peer_id) { - let mut sender = peer.sender.clone(); - task::spawn(async move { - let _ = sender.send(msg).await; - }); + Ok(msg_str) => { + let sender = { + let mut state = state_clone.lock().unwrap(); + if let Some(peer) = state.peers.get_mut(&peer_id) { + Some(peer.sender.clone()) + } else { + None + } + }; + + if let Some(mut sender) = sender { + trace!("Sending {}", msg_str); + let _ = sender.send(msg_str).await; } } Err(err) => {