diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index c2defe2d93..341a570b68 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -900,6 +900,7 @@ bool PeerConnection::Initialize( const PeerConnectionInterface::RTCConfiguration& configuration, PeerConnectionDependencies dependencies) { RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK_RUNS_SERIALIZED(&use_media_transport_race_checker_); TRACE_EVENT0("webrtc", "PeerConnection::Initialize"); RTCError config_error = ValidateConfiguration(configuration); @@ -1029,6 +1030,7 @@ bool PeerConnection::Initialize( stats_collector_ = RTCStatsCollector::Create(this); configuration_ = configuration; + use_media_transport_ = configuration.use_media_transport; // Obtain a certificate from RTCConfiguration if any were provided (optional). rtc::scoped_refptr certificate; @@ -1144,6 +1146,7 @@ RTCError PeerConnection::ValidateConfiguration( } rtc::scoped_refptr PeerConnection::local_streams() { + RTC_DCHECK_RUN_ON(signaling_thread()); RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified " "Plan SdpSemantics. Please use GetSenders " "instead."; @@ -1151,6 +1154,7 @@ rtc::scoped_refptr PeerConnection::local_streams() { } rtc::scoped_refptr PeerConnection::remote_streams() { + RTC_DCHECK_RUN_ON(signaling_thread()); RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified " "Plan SdpSemantics. Please use GetReceivers " "instead."; @@ -1624,6 +1628,7 @@ void PeerConnection::OnNegotiationNeeded() { rtc::scoped_refptr PeerConnection::CreateSender( const std::string& kind, const std::string& stream_id) { + RTC_DCHECK_RUN_ON(signaling_thread()); RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified " "Plan SdpSemantics. Please use AddTransceiver " "instead."; @@ -1714,6 +1719,7 @@ PeerConnection::GetReceiversInternal() const { std::vector> PeerConnection::GetTransceivers() const { + RTC_DCHECK_RUN_ON(signaling_thread()); RTC_CHECK(IsUnifiedPlan()) << "GetTransceivers is only supported with Unified Plan SdpSemantics."; std::vector> all_transceivers; @@ -1867,6 +1873,7 @@ rtc::scoped_refptr PeerConnection::CreateDataChannel( void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer, const RTCOfferAnswerOptions& options) { + RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "PeerConnection::CreateOffer"); if (!observer) { @@ -2023,6 +2030,7 @@ void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer, void PeerConnection::SetLocalDescription( SetSessionDescriptionObserver* observer, SessionDescriptionInterface* desc_ptr) { + RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "PeerConnection::SetLocalDescription"); // The SetLocalDescription contract is that we take ownership of the session @@ -2382,6 +2390,7 @@ void PeerConnection::SetRemoteDescription( void PeerConnection::SetRemoteDescription( std::unique_ptr desc, rtc::scoped_refptr observer) { + RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "PeerConnection::SetRemoteDescription"); if (!observer) { @@ -3234,11 +3243,14 @@ const cricket::ContentInfo* PeerConnection::FindMediaSectionForTransceiver( } PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() { + RTC_DCHECK_RUN_ON(signaling_thread()); return configuration_; } bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration, RTCError* error) { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK_RUNS_SERIALIZED(&use_media_transport_race_checker_); TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration"); if (IsClosed()) { RTC_LOG(LS_ERROR) << "SetConfiguration: PeerConnection is closed."; @@ -3394,6 +3406,7 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration, } configuration_ = modified_config; + use_media_transport_ = configuration.use_media_transport; return SafeSetError(RTCErrorType::NONE, error); } @@ -6937,6 +6950,7 @@ bool PeerConnection::OnTransportChanged( RtpTransportInternal* rtp_transport, cricket::DtlsTransportInternal* dtls_transport, MediaTransportInterface* media_transport) { + RTC_DCHECK_RUNS_SERIALIZED(&use_media_transport_race_checker_); bool ret = true; auto base_channel = GetChannel(mid); if (base_channel) { @@ -6946,7 +6960,7 @@ bool PeerConnection::OnTransportChanged( sctp_transport_->SetDtlsTransport(dtls_transport); } - if (configuration_.use_media_transport) { + if (use_media_transport_) { // Only pass media transport to call object if media transport is used // for media (and not data channel). call_->MediaTransportChange(media_transport); diff --git a/pc/peer_connection.h b/pc/peer_connection.h index 06404588d2..3d22bf4fd7 100644 --- a/pc/peer_connection.h +++ b/pc/peer_connection.h @@ -29,6 +29,7 @@ #include "pc/stats_collector.h" #include "pc/stream_collection.h" #include "pc/webrtc_session_description_factory.h" +#include "rtc_base/race_checker.h" #include "rtc_base/unique_id_generator.h" namespace webrtc { @@ -303,8 +304,10 @@ class PeerConnection : public PeerConnectionInternal, // Plan B helpers for getting the voice/video media channels for the single // audio/video transceiver, if it exists. - cricket::VoiceMediaChannel* voice_media_channel() const; - cricket::VideoMediaChannel* video_media_channel() const; + cricket::VoiceMediaChannel* voice_media_channel() const + RTC_RUN_ON(signaling_thread()); + cricket::VideoMediaChannel* video_media_channel() const + RTC_RUN_ON(signaling_thread()); std::vector>> GetSendersInternal() const; @@ -313,9 +316,9 @@ class PeerConnection : public PeerConnectionInternal, GetReceiversInternal() const; rtc::scoped_refptr> - GetAudioTransceiver() const; + GetAudioTransceiver() const RTC_RUN_ON(signaling_thread()); rtc::scoped_refptr> - GetVideoTransceiver() const; + GetVideoTransceiver() const RTC_RUN_ON(signaling_thread()); rtc::scoped_refptr> GetFirstAudioTransceiver() const; @@ -328,16 +331,20 @@ class PeerConnection : public PeerConnectionInternal, const RtpSenderInfo& remote_sender_info) RTC_RUN_ON(signaling_thread()); rtc::scoped_refptr RemoveAndStopReceiver( - const RtpSenderInfo& remote_sender_info); + const RtpSenderInfo& remote_sender_info) RTC_RUN_ON(signaling_thread()); // May be called either by AddStream/RemoveStream, or when a track is // added/removed from a stream previously added via AddStream. - void AddAudioTrack(AudioTrackInterface* track, MediaStreamInterface* stream); + void AddAudioTrack(AudioTrackInterface* track, MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); void RemoveAudioTrack(AudioTrackInterface* track, - MediaStreamInterface* stream); - void AddVideoTrack(VideoTrackInterface* track, MediaStreamInterface* stream); + MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); + void AddVideoTrack(VideoTrackInterface* track, MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); void RemoveVideoTrack(VideoTrackInterface* track, - MediaStreamInterface* stream); + MediaStreamInterface* stream) + RTC_RUN_ON(signaling_thread()); // AddTrack implementation when Unified Plan is specified. RTCErrorOr> AddTrackUnifiedPlan( @@ -346,7 +353,8 @@ class PeerConnection : public PeerConnectionInternal, // AddTrack implementation when Plan B is specified. RTCErrorOr> AddTrackPlanB( rtc::scoped_refptr track, - const std::vector& stream_ids); + const std::vector& stream_ids) + RTC_RUN_ON(signaling_thread()); // Returns the first RtpTransceiver suitable for a newly added track, if such // transceiver is available. @@ -450,7 +458,7 @@ class PeerConnection : public PeerConnectionInternal, rtc::scoped_refptr> transceiver, const cricket::ContentInfo& content, - const cricket::ContentGroup* bundle_group); + const cricket::ContentGroup* bundle_group) RTC_RUN_ON(signaling_thread()); // Either creates or destroys the local data channel according to the given // media section. @@ -467,21 +475,25 @@ class PeerConnection : public PeerConnectionInternal, size_t mline_index, const cricket::ContentInfo& content, const cricket::ContentInfo* old_local_content, - const cricket::ContentInfo* old_remote_content); + const cricket::ContentInfo* old_remote_content) + RTC_RUN_ON(signaling_thread()); // Returns the RtpTransceiver, if found, that is associated to the given MID. rtc::scoped_refptr> - GetAssociatedTransceiver(const std::string& mid) const; + GetAssociatedTransceiver(const std::string& mid) const + RTC_RUN_ON(signaling_thread()); // Returns the RtpTransceiver, if found, that was assigned to the given mline // index in CreateOffer. rtc::scoped_refptr> - GetTransceiverByMLineIndex(size_t mline_index) const; + GetTransceiverByMLineIndex(size_t mline_index) const + RTC_RUN_ON(signaling_thread()); // Returns an RtpTransciever, if available, that can be used to receive the // given media type according to JSEP rules. rtc::scoped_refptr> - FindAvailableTransceiverToReceive(cricket::MediaType media_type) const; + FindAvailableTransceiverToReceive(cricket::MediaType media_type) const + RTC_RUN_ON(signaling_thread()); // Returns the media section in the given session description that is // associated with the RtpTransceiver. Returns null if none found or this @@ -490,7 +502,8 @@ class PeerConnection : public PeerConnectionInternal, const cricket::ContentInfo* FindMediaSectionForTransceiver( rtc::scoped_refptr> transceiver, - const SessionDescriptionInterface* sdesc) const; + const SessionDescriptionInterface* sdesc) const + RTC_RUN_ON(signaling_thread()); // Runs the algorithm **set the associated remote streams** specified in // https://w3c.github.io/webrtc-pc/#set-associated-remote-streams. @@ -530,17 +543,21 @@ class PeerConnection : public PeerConnectionInternal, // the local MediaStreams and DataChannels. void GetOptionsForOffer(const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options); + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); void GetOptionsForPlanBOffer( const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options); + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); void GetOptionsForUnifiedPlanOffer( const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options); + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); - RTCError HandleLegacyOfferOptions(const RTCOfferAnswerOptions& options); + RTCError HandleLegacyOfferOptions(const RTCOfferAnswerOptions& options) + RTC_RUN_ON(signaling_thread()); void RemoveRecvDirectionFromReceivingTransceiversOfType( cricket::MediaType media_type); void AddUpToOneReceivingTransceiverOfType(cricket::MediaType media_type); @@ -551,15 +568,18 @@ class PeerConnection : public PeerConnectionInternal, // Returns a MediaSessionOptions struct with options decided by // |constraints|, the local MediaStreams and DataChannels. void GetOptionsForAnswer(const RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options); + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); void GetOptionsForPlanBAnswer( const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options); + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); void GetOptionsForUnifiedPlanAnswer( const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options, - cricket::MediaSessionOptions* session_options); + cricket::MediaSessionOptions* session_options) + RTC_RUN_ON(signaling_thread()); // Generates MediaDescriptionOptions for the |session_opts| based on existing // local description or remote description. @@ -628,7 +648,8 @@ class PeerConnection : public PeerConnectionInternal, // For each new or removed StreamParam, OnLocalSenderSeen or // OnLocalSenderRemoved is invoked. void UpdateLocalSenders(const std::vector& streams, - cricket::MediaType media_type); + cricket::MediaType media_type) + RTC_RUN_ON(signaling_thread()); // Triggered when a local sender has been seen for the first time in a local // session description. @@ -636,7 +657,8 @@ class PeerConnection : public PeerConnectionInternal, // streams in the local SessionDescription can be mapped to a MediaStreamTrack // in a MediaStream in |local_streams_| void OnLocalSenderAdded(const RtpSenderInfo& sender_info, - cricket::MediaType media_type); + cricket::MediaType media_type) + RTC_RUN_ON(signaling_thread()); // Triggered when a local sender has been removed from a local session // description. @@ -686,7 +708,7 @@ class PeerConnection : public PeerConnectionInternal, // to the user. If this is false, Plan B semantics are assumed. // TODO(bugs.webrtc.org/8530): Flip the default to be Unified Plan once // sufficient time has passed. - bool IsUnifiedPlan() const { + bool IsUnifiedPlan() const RTC_RUN_ON(signaling_thread()) { return configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan; } @@ -694,10 +716,12 @@ class PeerConnection : public PeerConnectionInternal, // unique. To support legacy end points that do not supply a=mid lines, this // method will modify the session description to add MIDs generated according // to the SDP semantics. - void FillInMissingRemoteMids(cricket::SessionDescription* remote_description); + void FillInMissingRemoteMids(cricket::SessionDescription* remote_description) + RTC_RUN_ON(signaling_thread()); // Is there an RtpSender of the given type? - bool HasRtpSender(cricket::MediaType type) const; + bool HasRtpSender(cricket::MediaType type) const + RTC_RUN_ON(signaling_thread()); // Return the RtpSender with the given track attached. rtc::scoped_refptr> @@ -818,8 +842,8 @@ class PeerConnection : public PeerConnectionInternal, const cricket::SessionDescription* description); // Push the media parts of the local or remote session description // down to all of the channels. - RTCError PushdownMediaDescription(SdpType type, - cricket::ContentSource source); + RTCError PushdownMediaDescription(SdpType type, cricket::ContentSource source) + RTC_RUN_ON(signaling_thread()); bool PushdownSctpParameters_n(cricket::ContentSource source); RTCError PushdownTransportDescription(cricket::ContentSource source, @@ -854,12 +878,14 @@ class PeerConnection : public PeerConnectionInternal, RTC_RUN_ON(signaling_thread()); // Deletes the corresponding channel of contents that don't exist in |desc|. // |desc| can be null. This means that all channels are deleted. - void RemoveUnusedChannels(const cricket::SessionDescription* desc); + void RemoveUnusedChannels(const cricket::SessionDescription* desc) + RTC_RUN_ON(signaling_thread()); // Allocates media channels based on the |desc|. If |desc| doesn't have // the BUNDLE option, this method will disable BUNDLE in PortAllocator. // This method will also delete any existing media channels before creating. - RTCError CreateChannels(const cricket::SessionDescription& desc); + RTCError CreateChannels(const cricket::SessionDescription& desc) + RTC_RUN_ON(signaling_thread()); // If the BUNDLE policy is max-bundle, then we know for sure that all // transports will be bundled from the start. This method returns the BUNDLE @@ -867,12 +893,15 @@ class PeerConnection : public PeerConnectionInternal, // error is returned if max-bundle is specified but the session description // does not have a BUNDLE group. RTCErrorOr GetEarlyBundleGroup( - const cricket::SessionDescription& desc) const; + const cricket::SessionDescription& desc) const + RTC_RUN_ON(signaling_thread()); // Helper methods to create media channels. - cricket::VoiceChannel* CreateVoiceChannel(const std::string& mid); - cricket::VideoChannel* CreateVideoChannel(const std::string& mid); - bool CreateDataChannel(const std::string& mid); + cricket::VoiceChannel* CreateVoiceChannel(const std::string& mid) + RTC_RUN_ON(signaling_thread()); + cricket::VideoChannel* CreateVideoChannel(const std::string& mid) + RTC_RUN_ON(signaling_thread()); + bool CreateDataChannel(const std::string& mid) RTC_RUN_ON(signaling_thread()); bool CreateSctpTransport_n(const std::string& mid); // For bundling. @@ -901,7 +930,8 @@ class PeerConnection : public PeerConnectionInternal, bool HasRtcpMuxEnabled(const cricket::ContentInfo* content); // Below methods are helper methods which verifies SDP. RTCError ValidateSessionDescription(const SessionDescriptionInterface* sdesc, - cricket::ContentSource source); + cricket::ContentSource source) + RTC_RUN_ON(signaling_thread()); // Check if a call to SetLocalDescription is acceptable with a session // description of the given type. @@ -996,7 +1026,7 @@ class PeerConnection : public PeerConnectionInternal, // Returns the CryptoOptions for this PeerConnection. This will always // return the RTCConfiguration.crypto_options if set and will only default // back to the PeerConnectionFactory settings if nothing was set. - CryptoOptions GetCryptoOptions(); + CryptoOptions GetCryptoOptions() RTC_RUN_ON(signaling_thread()); // Returns rtp transport, result can not be nullptr. RtpTransportInternal* GetRtpTransport(const std::string& mid) { @@ -1007,7 +1037,8 @@ class PeerConnection : public PeerConnectionInternal, // Returns media transport, if PeerConnection was created with configuration // to use media transport. Otherwise returns nullptr. - MediaTransportInterface* GetMediaTransport(const std::string& mid) { + MediaTransportInterface* GetMediaTransport(const std::string& mid) + RTC_RUN_ON(signaling_thread()) { auto media_transport = transport_controller_->GetMediaTransport(mid); RTC_DCHECK((configuration_.use_media_transport || configuration_.use_media_transport_for_data_channels) == @@ -1050,7 +1081,16 @@ class PeerConnection : public PeerConnectionInternal, IceGatheringState ice_gathering_state_ RTC_GUARDED_BY(signaling_thread()) = kIceGatheringNew; - PeerConnectionInterface::RTCConfiguration configuration_; + PeerConnectionInterface::RTCConfiguration configuration_ + RTC_GUARDED_BY(signaling_thread()); + + // Cache configuration_.use_media_transport so that we can access it from + // other threads. + // TODO(bugs.webrtc.org/9987): Caching just this bool and allowing the data + // it's derived from to change is not necessarily sound. Stop doing it. + rtc::RaceChecker use_media_transport_race_checker_; + bool use_media_transport_ RTC_GUARDED_BY(use_media_transport_race_checker_) = + configuration_.use_media_transport; // TODO(zstein): |async_resolver_factory_| can currently be nullptr if it // is not injected. It should be required once chromium supplies it.