From efb361ce7ceed01eddb00adb5f776e600fbcce4e Mon Sep 17 00:00:00 2001 From: Tommi Date: Tue, 9 May 2023 16:41:51 +0200 Subject: [PATCH] Register datachannel observer without blocking. This is especially needed for datachannels that get created in response to an OPEN message and RegisterObserver() is called from within the OnDataChannel callback. More details in the associated bug. Bug: webrtc:15165 Change-Id: I833db6c3c503623d482808dc5a02f03b9821a5f6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304721 Reviewed-by: Florent Castelli Commit-Queue: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#40032} --- pc/sctp_data_channel.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pc/sctp_data_channel.cc b/pc/sctp_data_channel.cc index 3fed03ca11..e024c60970 100644 --- a/pc/sctp_data_channel.cc +++ b/pc/sctp_data_channel.cc @@ -381,17 +381,22 @@ void SctpDataChannel::RegisterObserver(DataChannelObserver* observer) { } } - // Now do the observer registration on the network thread. - auto register_observer = [&] { - RTC_DCHECK_RUN_ON(network_thread_); - observer_ = observer; - DeliverQueuedReceivedData(); + // Now do the observer registration on the network thread. In the common case, + // we'll do this asynchronously via `PostTask()`. For that reason we grab + // a reference to ourselves while the task is in flight. We can't use + // `SafeTask(network_safety_, ...)` for this since we can't assume that we + // have a transport (network_safety_ represents the transport connection). + rtc::scoped_refptr me(this); + auto register_observer = [me = std::move(me), observer = observer] { + RTC_DCHECK_RUN_ON(me->network_thread_); + me->observer_ = observer; + me->DeliverQueuedReceivedData(); }; if (network_thread_ == current_thread) { register_observer(); } else { - network_thread_->BlockingCall(std::move(register_observer)); + network_thread_->PostTask(std::move(register_observer)); } }