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.
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<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) {
register_observer();
} else {
network_thread_->BlockingCall(std::move(register_observer));
network_thread_->PostTask(std::move(register_observer));
}
}