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 <orphis@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40032}
This commit is contained in:
Tommi 2023-05-09 16:41:51 +02:00 committed by WebRTC LUCI CQ
parent 353413eb38
commit efb361ce7c

View File

@ -381,17 +381,22 @@ void SctpDataChannel::RegisterObserver(DataChannelObserver* observer) {
} }
} }
// Now do the observer registration on the network thread. // Now do the observer registration on the network thread. In the common case,
auto register_observer = [&] { // we'll do this asynchronously via `PostTask()`. For that reason we grab
RTC_DCHECK_RUN_ON(network_thread_); // a reference to ourselves while the task is in flight. We can't use
observer_ = observer; // `SafeTask(network_safety_, ...)` for this since we can't assume that we
DeliverQueuedReceivedData(); // have a transport (network_safety_ represents the transport connection).
rtc::scoped_refptr<SctpDataChannel> 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) { if (network_thread_ == current_thread) {
register_observer(); register_observer();
} else { } else {
network_thread_->BlockingCall(std::move(register_observer)); network_thread_->PostTask(std::move(register_observer));
} }
} }