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}
diff --git a/pc/sctp_data_channel.cc b/pc/sctp_data_channel.cc
index 3fed03c..e024c60 100644
--- a/pc/sctp_data_channel.cc
+++ b/pc/sctp_data_channel.cc
@@ -381,17 +381,22 @@
}
}
- // 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));
}
}