Skip to content

Commit a74b96d

Browse files
authored
rtp_sender: Use a watch channel for send_called (#588)
This removes the need for some mutexes
1 parent 0e5c862 commit a74b96d

File tree

2 files changed

+21
-15
lines changed

2 files changed

+21
-15
lines changed

webrtc/src/rtp_transceiver/rtp_sender/mod.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use ice::rand::generate_crypto_random_string;
88
use interceptor::stream_info::StreamInfo;
99
use interceptor::{Attributes, Interceptor, RTCPReader, RTPWriter};
1010
use portable_atomic::AtomicBool;
11-
use tokio::sync::{mpsc, Mutex, Notify};
11+
use tokio::sync::{watch, Mutex, Notify};
1212
use util::sync::Mutex as SyncMutex;
1313

1414
use super::srtp_writer_future::SequenceTransformer;
@@ -27,7 +27,6 @@ use crate::track::track_local::{
2727
};
2828

2929
pub(crate) struct RTPSenderInternal {
30-
pub(crate) send_called_rx: Mutex<mpsc::Receiver<()>>,
3130
pub(crate) stop_called_rx: Arc<Notify>,
3231
pub(crate) stop_called_signal: Arc<AtomicBool>,
3332
}
@@ -71,7 +70,7 @@ pub struct RTCRtpSender {
7170

7271
rtp_transceiver: SyncMutex<Option<Weak<RTCRtpTransceiver>>>,
7372

74-
send_called_tx: SyncMutex<Option<mpsc::Sender<()>>>,
73+
send_called: watch::Sender<bool>,
7574
stop_called_tx: Arc<Notify>,
7675
stop_called_signal: Arc<AtomicBool>,
7776

@@ -102,13 +101,12 @@ impl RTCRtpSender {
102101
32,
103102
b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
104103
);
105-
let (send_called_tx, send_called_rx) = mpsc::channel(1);
104+
let (send_called, _) = watch::channel(false);
106105
let stop_called_tx = Arc::new(Notify::new());
107106
let stop_called_rx = stop_called_tx.clone();
108107
let stop_called_signal = Arc::new(AtomicBool::new(false));
109108

110109
let internal = Arc::new(RTPSenderInternal {
111-
send_called_rx: Mutex::new(send_called_rx),
112110
stop_called_rx,
113111
stop_called_signal: Arc::clone(&stop_called_signal),
114112
});
@@ -141,7 +139,7 @@ impl RTCRtpSender {
141139

142140
rtp_transceiver: SyncMutex::new(None),
143141

144-
send_called_tx: SyncMutex::new(Some(send_called_tx)),
142+
send_called,
145143
stop_called_tx,
146144
stop_called_signal,
147145

@@ -435,7 +433,7 @@ impl RTCRtpSender {
435433
*write_stream.interceptor_rtp_writer.lock().await = Some(rtp_writer);
436434
}
437435

438-
self.send_called_tx.lock().take();
436+
self.send_called.send_replace(true);
439437
Ok(())
440438
}
441439

@@ -469,10 +467,8 @@ impl RTCRtpSender {
469467
&self,
470468
b: &mut [u8],
471469
) -> Result<(Vec<Box<dyn rtcp::packet::Packet + Send + Sync>>, Attributes)> {
472-
let mut send_called_rx = self.internal.send_called_rx.lock().await;
473-
474470
tokio::select! {
475-
_ = send_called_rx.recv() => {
471+
_ = self.wait_for_send() => {
476472
let rtcp_interceptor = {
477473
let track_encodings = self.track_encodings.lock().await;
478474
track_encodings.first().map(|e|e.rtcp_interceptor.clone())
@@ -503,10 +499,8 @@ impl RTCRtpSender {
503499
b: &mut [u8],
504500
rid: &str,
505501
) -> Result<(Vec<Box<dyn rtcp::packet::Packet + Send + Sync>>, Attributes)> {
506-
let mut send_called_rx = self.internal.send_called_rx.lock().await;
507-
508502
tokio::select! {
509-
_ = send_called_rx.recv() => {
503+
_ = self.wait_for_send() => {
510504
let rtcp_interceptor = {
511505
let track_encodings = self.track_encodings.lock().await;
512506
track_encodings.iter().find(|e| e.track.rid() == Some(rid)).map(|e| e.rtcp_interceptor.clone())
@@ -544,10 +538,19 @@ impl RTCRtpSender {
544538
self.seq_trans.enable()
545539
}
546540

541+
/// Will asynchronously block/wait until send() has been called
542+
///
543+
/// Note that it could return if underlying channel is closed,
544+
/// however this shouldn't happen as we have a reference to self
545+
/// which again owns the underlying channel.
546+
pub async fn wait_for_send(&self) {
547+
let mut watch = self.send_called.subscribe();
548+
let _ = watch.wait_for(|r| *r).await;
549+
}
550+
547551
/// has_sent tells if data has been ever sent for this instance
548552
pub(crate) fn has_sent(&self) -> bool {
549-
let send_called_tx = self.send_called_tx.lock();
550-
send_called_tx.is_none()
553+
*self.send_called.borrow()
551554
}
552555

553556
/// has_stopped tells if stop has been called

webrtc/src/rtp_transceiver/rtp_sender/rtp_sender_test.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use bytes::Bytes;
22
use portable_atomic::AtomicU64;
3+
use std::sync::atomic::Ordering;
4+
use std::sync::Arc;
5+
use tokio::sync::mpsc;
36
use tokio::time::Duration;
47
use waitgroup::WaitGroup;
58

0 commit comments

Comments
 (0)