tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit d88df7a46fb0d36e937e227402b2d9b88163a79e
parent 142a49eca33a5b2a77315e4ed65b428ed204b416
Author: Dan Baker <dbaker@mozilla.com>
Date:   Mon,  1 Dec 2025 21:01:58 -0700

Bug 2000941 - Vendor libwebrtc from fdb1f408c1

Upstream commit: https://webrtc.googlesource.com/src/+/fdb1f408c152eb07a775572b1b771a1ac82cec64
    Activating thread guard for state in JsepSessionDescription

    Bug: webrtc:442220720
    Change-Id: I54c78ee45e821d49f2de3e6ed35ee04cd293a191
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/407045
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45659}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/api/jsep.h | 3+--
Mthird_party/libwebrtc/api/jsep_session_description.h | 3++-
Mthird_party/libwebrtc/pc/jsep_session_description.cc | 53+++++++++++++++++++++++++++++------------------------
Mthird_party/libwebrtc/pc/peer_connection.cc | 141++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mthird_party/libwebrtc/pc/peer_connection.h | 39+++++++++++++++++++++++++++++++++++++++
Mthird_party/libwebrtc/pc/peer_connection_proxy.h | 53+++++++++++++++++++++++++++--------------------------
Mthird_party/libwebrtc/pc/sdp_offer_answer.cc | 42++++++++++++++++--------------------------
Mthird_party/libwebrtc/pc/webrtc_session_description_factory.cc | 1+
9 files changed, 236 insertions(+), 103 deletions(-)

diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor @@ -1,4 +1,4 @@ # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc -libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T03:58:33.271617+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T04:01:43.049914+00:00. # base of lastest vendoring -85c183fd32 +fdb1f408c1 diff --git a/third_party/libwebrtc/api/jsep.h b/third_party/libwebrtc/api/jsep.h @@ -249,12 +249,11 @@ class SessionDescriptionInternal { // This method is necessarily `protected`, and not private, while // the SessionDescriptionInterface implementation is being consolidated // into a single class. - SequenceChecker& sequence_checker() { return sequence_checker_; } + const SequenceChecker* sequence_checker() const { return &sequence_checker_; } private: RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_{ SequenceChecker::kDetached}; - const SdpType sdp_type_; const std::string id_; const std::string version_; diff --git a/third_party/libwebrtc/api/jsep_session_description.h b/third_party/libwebrtc/api/jsep_session_description.h @@ -54,7 +54,8 @@ class JsepSessionDescription final : public SessionDescriptionInterface { bool ToString(std::string* out) const override; private: - std::vector<IceCandidateCollection> candidate_collection_; + std::vector<IceCandidateCollection> candidate_collection_ + RTC_GUARDED_BY(sequence_checker()); bool IsValidMLineIndex(int index) const; bool GetMediasectionIndex(const IceCandidate* candidate, size_t* index) const; diff --git a/third_party/libwebrtc/pc/jsep_session_description.cc b/third_party/libwebrtc/pc/jsep_session_description.cc @@ -169,6 +169,12 @@ size_t SessionDescriptionInternal::mediasection_count() const { } void SessionDescriptionInternal::RelinquishThreadOwnership() { + // Ideally we should require that the method can only be called from the + // thread that the sequence checker is currently attached to. However that's + // not compatible with some cases outside of webrtc where initializations + // happens on one thread and then the object is moved to a second thread (e.g. + // signaling) where a call is made into webrtc. At that point we'd hit a + // dcheck like this in webrtc: RTC_DCHECK_RUN_ON(&sequence_checker_); sequence_checker_.Detach(); } @@ -203,22 +209,23 @@ JsepSessionDescription::~JsepSessionDescription() {} std::unique_ptr<SessionDescriptionInterface> JsepSessionDescription::Clone() const { + RTC_DCHECK_RUN_ON(sequence_checker()); return std::make_unique<JsepSessionDescription>( sdp_type(), description() ? description()->Clone() : nullptr, id(), version(), CloneCandidateCollection(candidate_collection_)); } bool JsepSessionDescription::AddCandidate(const IceCandidate* candidate) { + RTC_DCHECK_RUN_ON(sequence_checker()); if (!candidate) return false; - size_t mediasection_index = 0; - if (!GetMediasectionIndex(candidate, &mediasection_index)) { + size_t index = 0; + if (!GetMediasectionIndex(candidate, &index)) { return false; } - const std::string& mediasection_mid = - description()->contents()[mediasection_index].mid(); + ContentInfo& content = description()->contents()[index]; const TransportInfo* transport_info = - description()->GetTransportInfoByName(mediasection_mid); + description()->GetTransportInfoByName(content.mid()); if (!transport_info) { return false; } @@ -231,45 +238,43 @@ bool JsepSessionDescription::AddCandidate(const IceCandidate* candidate) { updated_candidate.set_password(transport_info->description.ice_pwd); } - // Use `mediasection_mid` as the mid for the updated candidate. The + // Use `content.mid()` as the mid for the updated candidate. The // `candidate->sdp_mid()` property *should* be the same. However, in some // cases specifying an empty mid but a valid index is a way to add a candidate // without knowing (or caring about) the mid. This is done in several tests. RTC_DCHECK(candidate->sdp_mid().empty() || - candidate->sdp_mid() == mediasection_mid) - << "sdp_mid='" << candidate->sdp_mid() << "' mediasection_mid='" - << mediasection_mid << "'"; + candidate->sdp_mid() == content.mid()) + << "sdp_mid='" << candidate->sdp_mid() << "' content.mid()='" + << content.mid() << "'"; auto updated_candidate_wrapper = std::make_unique<IceCandidate>( - mediasection_mid, static_cast<int>(mediasection_index), - updated_candidate); - if (!candidate_collection_[mediasection_index].HasCandidate( - updated_candidate_wrapper.get())) { - candidate_collection_[mediasection_index].add( - std::move(updated_candidate_wrapper)); - UpdateConnectionAddress( - candidate_collection_[mediasection_index], - description()->contents()[mediasection_index].media_description()); + content.mid(), static_cast<int>(index), updated_candidate); + IceCandidateCollection& candidates = candidate_collection_[index]; + if (!candidates.HasCandidate(updated_candidate_wrapper.get())) { + candidates.add(std::move(updated_candidate_wrapper)); + UpdateConnectionAddress(candidates, content.media_description()); } return true; } bool JsepSessionDescription::RemoveCandidate(const IceCandidate* candidate) { - size_t mediasection_index = 0u; - if (!GetMediasectionIndex(candidate, &mediasection_index)) { + RTC_DCHECK_RUN_ON(sequence_checker()); + size_t index = 0u; + if (!GetMediasectionIndex(candidate, &index)) { return false; } - if (!candidate_collection_[mediasection_index].remove(candidate)) { + IceCandidateCollection& candidates = candidate_collection_[index]; + if (!candidates.remove(candidate)) { return false; } - UpdateConnectionAddress( - candidate_collection_[mediasection_index], - description()->contents()[mediasection_index].media_description()); + UpdateConnectionAddress(candidates, + description()->contents()[index].media_description()); return true; } const IceCandidateCollection* JsepSessionDescription::candidates( size_t mediasection_index) const { + RTC_DCHECK_RUN_ON(sequence_checker()); if (mediasection_index >= candidate_collection_.size()) return nullptr; return &candidate_collection_[mediasection_index]; diff --git a/third_party/libwebrtc/pc/peer_connection.cc b/third_party/libwebrtc/pc/peer_connection.cc @@ -360,6 +360,63 @@ void NoteServerUsage(UsagePattern& usage_pattern, } } +template <typename Observer, + typename std::enable_if_t< + std::is_same_v<Observer, SetSessionDescriptionObserver*>, + bool> = true> +absl::AnyInvocable<void() &&> ReportFailure(Observer& o, RTCError error) { + return [o = scoped_refptr<SetSessionDescriptionObserver>(o), + error = std::move(error)]() { o->OnFailure(error); }; +} + +template < + typename Observer, + typename std::enable_if_t< + std::is_same_v<Observer, + scoped_refptr<SetLocalDescriptionObserverInterface>>, + bool> = true> +absl::AnyInvocable<void() &&> ReportFailure(Observer& o, RTCError error) { + return [o = std::move(o), error = std::move(error)]() { + o->OnSetLocalDescriptionComplete(error); + }; +} + +template < + typename Observer, + typename std::enable_if_t< + std::is_same_v<Observer, + scoped_refptr<SetRemoteDescriptionObserverInterface>>, + bool> = true> +absl::AnyInvocable<void() &&> ReportFailure(Observer& o, RTCError error) { + return [o = std::move(o), error = std::move(error)]() { + o->OnSetRemoteDescriptionComplete(error); + }; +} + +// Checks if the observer and description pointers are valid. +// If there's an error, the function will return false and optionally +// notify the observer asynchronously of the error. +// If both are valid, the function will reset the thread ownership of +// the description object and return true. +template <typename Observer, typename Description> +bool CheckValidSetDescription(Observer& observer, + Description& desc, + Thread* signaling) { + if (!observer) { + RTC_LOG(LS_ERROR) << "Observer is NULL."; + return false; + } else if (!desc) { + signaling->PostTask( + ReportFailure(observer, RTCError(RTCErrorType::INVALID_PARAMETER, + "SessionDescription is NULL."))); + return false; + } + // Make sure the description object now considers the current thread its home + // by detaching from any potential previous thread. + desc->RelinquishThreadOwnership(); + return true; +} + } // namespace bool PeerConnectionInterface::RTCConfiguration::operator==( @@ -1428,16 +1485,28 @@ void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer, void PeerConnection::SetLocalDescription( SetSessionDescriptionObserver* observer, - SessionDescriptionInterface* desc_ptr) { - RTC_DCHECK_RUN_ON(signaling_thread()); - sdp_handler_->SetLocalDescription(observer, desc_ptr); + SessionDescriptionInterface* desc) { + if (!CheckValidSetDescription(observer, desc, signaling_thread())) + return; + + RunOnSignalingThread([this, desc, observer]() mutable { + RTC_DCHECK_RUN_ON(signaling_thread()); + sdp_handler_->SetLocalDescription(observer, desc); + }); } +// This method bypasses the proxy, so can be called from any thread. void PeerConnection::SetLocalDescription( std::unique_ptr<SessionDescriptionInterface> desc, scoped_refptr<SetLocalDescriptionObserverInterface> observer) { - RTC_DCHECK_RUN_ON(signaling_thread()); - sdp_handler_->SetLocalDescription(std::move(desc), observer); + if (!CheckValidSetDescription(observer, desc, signaling_thread())) + return; + + RunOnSignalingThread( + [this, desc = std::move(desc), observer = std::move(observer)]() mutable { + RTC_DCHECK_RUN_ON(signaling_thread()); + sdp_handler_->SetLocalDescription(std::move(desc), observer); + }); } void PeerConnection::SetLocalDescription( @@ -1454,16 +1523,27 @@ void PeerConnection::SetLocalDescription( void PeerConnection::SetRemoteDescription( SetSessionDescriptionObserver* observer, - SessionDescriptionInterface* desc_ptr) { - RTC_DCHECK_RUN_ON(signaling_thread()); - sdp_handler_->SetRemoteDescription(observer, desc_ptr); + SessionDescriptionInterface* desc) { + if (!CheckValidSetDescription(observer, desc, signaling_thread())) + return; + + RunOnSignalingThread([this, desc, observer]() mutable { + RTC_DCHECK_RUN_ON(signaling_thread()); + sdp_handler_->SetRemoteDescription(observer, desc); + }); } void PeerConnection::SetRemoteDescription( std::unique_ptr<SessionDescriptionInterface> desc, scoped_refptr<SetRemoteDescriptionObserverInterface> observer) { - RTC_DCHECK_RUN_ON(signaling_thread()); - sdp_handler_->SetRemoteDescription(std::move(desc), observer); + if (!CheckValidSetDescription(observer, desc, signaling_thread())) + return; + + RunOnSignalingThread( + [this, desc = std::move(desc), observer = std::move(observer)]() mutable { + RTC_DCHECK_RUN_ON(signaling_thread()); + sdp_handler_->SetRemoteDescription(std::move(desc), observer); + }); } PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() { @@ -1728,37 +1808,41 @@ scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport() const { } const SessionDescriptionInterface* PeerConnection::local_description() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return sdp_handler_->local_description(); + return HandleSessionDescriptionAccessor<&SdpStateProvider::local_description>( + local_description_clone_); } const SessionDescriptionInterface* PeerConnection::remote_description() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return sdp_handler_->remote_description(); + return HandleSessionDescriptionAccessor< + &SdpStateProvider::remote_description>(remote_description_clone_); } const SessionDescriptionInterface* PeerConnection::current_local_description() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return sdp_handler_->current_local_description(); + return HandleSessionDescriptionAccessor< + &SdpStateProvider::current_local_description>( + current_local_description_clone_); } const SessionDescriptionInterface* PeerConnection::current_remote_description() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return sdp_handler_->current_remote_description(); + return HandleSessionDescriptionAccessor< + &SdpStateProvider::current_remote_description>( + current_remote_description_clone_); } const SessionDescriptionInterface* PeerConnection::pending_local_description() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return sdp_handler_->pending_local_description(); + return HandleSessionDescriptionAccessor< + &SdpStateProvider::pending_local_description>( + pending_local_description_clone_); } const SessionDescriptionInterface* PeerConnection::pending_remote_description() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return sdp_handler_->pending_remote_description(); + return HandleSessionDescriptionAccessor< + &SdpStateProvider::pending_remote_description>( + pending_remote_description_clone_); } void PeerConnection::Close() { @@ -3034,4 +3118,17 @@ bool PeerConnection::CanAttemptDtlsStunPiggybacking() { env_.field_trials().IsEnabled("WebRTC-IceHandshakeDtls"); } +void PeerConnection::RunOnSignalingThread(absl::AnyInvocable<void() &&> task) { + if (signaling_thread()->IsCurrent()) { + std::move(task)(); + } else { + // Consider if we can use PostTask instead in some situations: + // signaling_thread()->PostTask( + // SafeTask(signaling_thread_safety_.flag(), std::move(task))); + // Currently we use BlockingCall() to be compatible with how the + // api proxies work by default. + signaling_thread()->BlockingCall([&] { std::move(task)(); }); + } +} + } // namespace webrtc diff --git a/third_party/libwebrtc/pc/peer_connection.h b/third_party/libwebrtc/pc/peer_connection.h @@ -629,6 +629,12 @@ class PeerConnection : public PeerConnectionInternal, bool CanAttemptDtlsStunPiggybacking(); + // Runs a task on the signaling thread. If the current thread is the signaling + // thread, the task will run immediately. Otherwise it will be posted to the + // signaling thread and run asynchronously behind the + // `signaling_thread_safety_` flag. + void RunOnSignalingThread(absl::AnyInvocable<void() &&> task); + const Environment env_; const scoped_refptr<ConnectionContext> context_; const PeerConnectionFactoryInterface::Options options_; @@ -734,6 +740,39 @@ class PeerConnection : public PeerConnectionInternal, std::unique_ptr<CodecLookupHelper> codec_lookup_helper_; + template <const SessionDescriptionInterface* (SdpStateProvider::*accessor)() + const> + const SessionDescriptionInterface* HandleSessionDescriptionAccessor( + std::unique_ptr<SessionDescriptionInterface>& clone) const { + if (signaling_thread()->IsCurrent()) { + RTC_DCHECK_RUN_ON(signaling_thread()); + return (sdp_handler_.get()->*accessor)(); + } + signaling_thread()->BlockingCall([&] { + RTC_DCHECK_RUN_ON(signaling_thread()); + const SessionDescriptionInterface* desc = + (sdp_handler_.get()->*accessor)(); + clone = desc ? desc->Clone() : nullptr; + }); + return clone.get(); + } + + // Optionally set clones of the properties as owned by SdpOfferAnswerHandler. + // When these properties are accessed from outside the signaling thread, + // we clone the description on the signaling thread and return a pointer to + // the clone instead. + mutable std::unique_ptr<SessionDescriptionInterface> local_description_clone_; + mutable std::unique_ptr<SessionDescriptionInterface> + remote_description_clone_; + mutable std::unique_ptr<SessionDescriptionInterface> + current_local_description_clone_; + mutable std::unique_ptr<SessionDescriptionInterface> + current_remote_description_clone_; + mutable std::unique_ptr<SessionDescriptionInterface> + pending_local_description_clone_; + mutable std::unique_ptr<SessionDescriptionInterface> + pending_remote_description_clone_; + // This variable needs to be the last one in the class. WeakPtrFactory<PeerConnection> weak_factory_; }; diff --git a/third_party/libwebrtc/pc/peer_connection_proxy.h b/third_party/libwebrtc/pc/peer_connection_proxy.h @@ -109,16 +109,17 @@ PROXY_METHOD2(RTCErrorOr<scoped_refptr<DataChannelInterface>>, CreateDataChannelOrError, const std::string&, const DataChannelInit*) -PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, local_description) -PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, remote_description) -PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, - current_local_description) -PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, - current_remote_description) -PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, - pending_local_description) -PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, - pending_remote_description) +BYPASS_PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, local_description) +BYPASS_PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, + remote_description) +BYPASS_PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, + current_local_description) +BYPASS_PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, + current_remote_description) +BYPASS_PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, + pending_local_description) +BYPASS_PROXY_CONSTMETHOD0(const SessionDescriptionInterface*, + pending_remote_description) PROXY_METHOD0(void, RestartIce) PROXY_METHOD2(void, CreateOffer, @@ -128,26 +129,26 @@ PROXY_METHOD2(void, CreateAnswer, CreateSessionDescriptionObserver*, const RTCOfferAnswerOptions&) -PROXY_METHOD2(void, - SetLocalDescription, - std::unique_ptr<SessionDescriptionInterface>, - scoped_refptr<SetLocalDescriptionObserverInterface>) +BYPASS_PROXY_METHOD2(void, + SetLocalDescription, + std::unique_ptr<SessionDescriptionInterface>, + scoped_refptr<SetLocalDescriptionObserverInterface>) PROXY_METHOD1(void, SetLocalDescription, scoped_refptr<SetLocalDescriptionObserverInterface>) -PROXY_METHOD2(void, - SetLocalDescription, - SetSessionDescriptionObserver*, - SessionDescriptionInterface*) +BYPASS_PROXY_METHOD2(void, + SetLocalDescription, + SetSessionDescriptionObserver*, + SessionDescriptionInterface*) PROXY_METHOD1(void, SetLocalDescription, SetSessionDescriptionObserver*) -PROXY_METHOD2(void, - SetRemoteDescription, - std::unique_ptr<SessionDescriptionInterface>, - scoped_refptr<SetRemoteDescriptionObserverInterface>) -PROXY_METHOD2(void, - SetRemoteDescription, - SetSessionDescriptionObserver*, - SessionDescriptionInterface*) +BYPASS_PROXY_METHOD2(void, + SetRemoteDescription, + std::unique_ptr<SessionDescriptionInterface>, + scoped_refptr<SetRemoteDescriptionObserverInterface>) +BYPASS_PROXY_METHOD2(void, + SetRemoteDescription, + SetSessionDescriptionObserver*, + SessionDescriptionInterface*) PROXY_METHOD1(bool, ShouldFireNegotiationNeededEvent, uint32_t) PROXY_METHOD0(PeerConnectionInterface::RTCConfiguration, GetConfiguration) PROXY_METHOD1(RTCError, diff --git a/third_party/libwebrtc/pc/sdp_offer_answer.cc b/third_party/libwebrtc/pc/sdp_offer_answer.cc @@ -966,14 +966,8 @@ class SdpOfferAnswerHandler::RemoteDescriptionOperation { desc_(std::move(desc)), observer_(std::move(observer)), operations_chain_callback_(std::move(operations_chain_callback)), - unified_plan_(handler_->IsUnifiedPlan()) { - if (!desc_) { - type_ = static_cast<SdpType>(-1); - InvalidParam("SessionDescription is NULL."); - } else { - type_ = desc_->GetType(); - } - } + type_(desc_->GetType()), + unified_plan_(handler_->IsUnifiedPlan()) {} ~RemoteDescriptionOperation() { RTC_DCHECK_RUN_ON(handler_->signaling_thread()); @@ -1190,7 +1184,7 @@ class SdpOfferAnswerHandler::RemoteDescriptionOperation { std::function<void()> operations_chain_callback_; RTCError error_ = RTCError::OK(); std::map<std::string, const ContentGroup*> bundle_groups_by_mid_; - SdpType type_; + const SdpType type_; const bool unified_plan_; }; // Used by parameterless SetLocalDescription() to create an offer or answer. @@ -1279,6 +1273,7 @@ class CreateSessionDescriptionObserverOperationWrapper // Completing the operation before invoking the observer allows the observer // to execute SetLocalDescription() without delay. operation_complete_callback_(); + desc->RelinquishThreadOwnership(); observer_->OnSuccess(desc); } @@ -1637,6 +1632,8 @@ void SdpOfferAnswerHandler::SetLocalDescription( SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc_ptr) { RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(desc_ptr); + RTC_DCHECK(observer); // Chain this operation. If asynchronous operations are pending on the chain, // this operation will be queued to be invoked, otherwise the contents of the // lambda will execute immediately. @@ -1672,6 +1669,8 @@ void SdpOfferAnswerHandler::SetLocalDescription( std::unique_ptr<SessionDescriptionInterface> desc, scoped_refptr<SetLocalDescriptionObserverInterface> observer) { RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(desc); + RTC_DCHECK(observer); // Chain this operation. If asynchronous operations are pending on the chain, // this operation will be queued to be invoked, otherwise the contents of the // lambda will execute immediately. @@ -1698,6 +1697,7 @@ void SdpOfferAnswerHandler::SetLocalDescription( void SdpOfferAnswerHandler::SetLocalDescription( SetSessionDescriptionObserver* observer) { RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(observer); SetLocalDescription(make_ref_counted<SetSessionDescriptionObserverAdapter>( weak_ptr_factory_.GetWeakPtr(), scoped_refptr<SetSessionDescriptionObserver>(observer))); @@ -1706,6 +1706,7 @@ void SdpOfferAnswerHandler::SetLocalDescription( void SdpOfferAnswerHandler::SetLocalDescription( scoped_refptr<SetLocalDescriptionObserverInterface> observer) { RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(observer); // The `create_sdp_observer` handles performing DoSetLocalDescription() with // the resulting description as well as completing the operation. auto create_sdp_observer = @@ -2015,6 +2016,8 @@ void SdpOfferAnswerHandler::SetRemoteDescription( SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc_ptr) { RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(observer); + RTC_DCHECK(desc_ptr); // Chain this operation. If asynchronous operations are pending on the chain, // this operation will be queued to be invoked, otherwise the contents of the // lambda will execute immediately. @@ -2046,6 +2049,8 @@ void SdpOfferAnswerHandler::SetRemoteDescription( std::unique_ptr<SessionDescriptionInterface> desc, scoped_refptr<SetRemoteDescriptionObserverInterface> observer) { RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(desc); + RTC_DCHECK(observer); // Chain this operation. If asynchronous operations are pending on the chain, // this operation will be queued to be invoked, otherwise the contents of the // lambda will execute immediately. @@ -2053,12 +2058,6 @@ void SdpOfferAnswerHandler::SetRemoteDescription( [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), observer, desc = std::move(desc)]( std::function<void()> operations_chain_callback) mutable { - if (!observer) { - RTC_DLOG(LS_ERROR) << "SetRemoteDescription - observer is NULL."; - operations_chain_callback(); - return; - } - // Abort early if `this_weak_ptr` is no longer valid. if (!this_weak_ptr) { observer->OnSetRemoteDescriptionComplete(RTCError( @@ -2431,17 +2430,8 @@ void SdpOfferAnswerHandler::DoSetLocalDescription( scoped_refptr<SetLocalDescriptionObserverInterface> observer) { RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::DoSetLocalDescription"); - - if (!observer) { - RTC_LOG(LS_ERROR) << "SetLocalDescription - observer is NULL."; - return; - } - - if (!desc) { - observer->OnSetLocalDescriptionComplete( - RTCError(RTCErrorType::INTERNAL_ERROR, "SessionDescription is NULL.")); - return; - } + RTC_DCHECK(desc); + RTC_DCHECK(observer); // If a session error has occurred the PeerConnection is in a possibly // inconsistent state so fail right away. diff --git a/third_party/libwebrtc/pc/webrtc_session_description_factory.cc b/third_party/libwebrtc/pc/webrtc_session_description_factory.cc @@ -401,6 +401,7 @@ void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionFailed( void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionSucceeded( CreateSessionDescriptionObserver* observer, std::unique_ptr<SessionDescriptionInterface> description) { + description->RelinquishThreadOwnership(); Post([observer = scoped_refptr<CreateSessionDescriptionObserver>(observer), description = std::move(description)]() mutable { observer->OnSuccess(description.release());