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:
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());