Introduce StopStandardAsync in RtpTransceiver Returns a task compatible with ScopedOperationsBatcher to avoid BlockingCall in UpdateTransceiversAndDataChannels. Bug: webrtc:42222804 Change-Id: I3289c44135109d69e5fc30687be017f12de96207 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/463260 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Cr-Commit-Position: refs/heads/main@{#47474}
diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index b0e736e..fe47e3a 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc
@@ -1089,6 +1089,28 @@ return RTCError::OK(); } +ScopedOperationsBatcher::BatchTaskWithFinalizer +RtpTransceiver::StopStandardAsync() { + RTC_DCHECK_RUN_ON(thread_); + RTC_DCHECK(unified_plan_); + + if (stopping_) { + return nullptr; + } + + auto stop_task = GetStopSendingAndReceiving(); + + return [this, stop_task = std::move(stop_task)]() mutable + -> RTCErrorOr<ScopedOperationsBatcher::FinalizerTask> { + RTC_DCHECK_RUN_ON(context()->worker_thread()); + std::move(stop_task)(); + return ScopedOperationsBatcher::FinalizerTask([this]() { + RTC_DCHECK_RUN_ON(thread_); + on_negotiation_needed_(); + }); + }; +} + void RtpTransceiver::StopInternal() { RTC_DCHECK_RUN_ON(thread_); auto stop_task = GetStopTransceiverProcedure();
diff --git a/pc/rtp_transceiver.h b/pc/rtp_transceiver.h index e455e3c..e5ace43 100644 --- a/pc/rtp_transceiver.h +++ b/pc/rtp_transceiver.h
@@ -55,6 +55,7 @@ #include "pc/rtp_sender.h" #include "pc/rtp_sender_proxy.h" #include "pc/rtp_transport_internal.h" +#include "pc/scoped_operations_batcher.h" #include "pc/session_description.h" #include "rtc_base/checks.h" #include "rtc_base/system/plan_b_only.h" @@ -331,6 +332,11 @@ [[nodiscard]] absl_nullable absl::AnyInvocable<void() &&> GetStopTransceiverProcedure(); + // Returns a task that stops the transceiver. + // The task must be executed on the worker thread. + // This is used by SdpOfferAnswerHandler to batch worker thread operations. + ScopedOperationsBatcher::BatchTaskWithFinalizer StopStandardAsync(); + // RtpTransceiverInterface implementation. MediaType media_type() const override; std::optional<std::string> mid() const override;
diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 7fc773a..2505c39 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc
@@ -4187,7 +4187,8 @@ // transceiver stopping. But if the rejection was caused by SDP // munging then we need to ensure the transceiver is stopping here. if (!transceiver->internal()->stopping()) { - transceiver->internal()->StopStandard(); + worker_tasks.AddWithFinalizer( + transceiver->internal()->StopStandardAsync()); } RTC_DCHECK(transceiver->internal()->stopping()); } else {