diff options
| author | Roxie Linden <roxie@lindenlab.com> | 2023-09-12 15:17:08 -0700 | 
|---|---|---|
| committer | Roxie Linden <roxie@lindenlab.com> | 2024-02-22 23:11:33 -0800 | 
| commit | a974a1517901eb0a93099853a89bf55904737cec (patch) | |
| tree | bf7496e58e72d3c3f9f0779305ea1e23192c6e55 | |
| parent | 6d81e64348009c1bb656fe500e9a08ab7f739311 (diff) | |
do some thread safety to prevent webrtc threads from conflicting with viewer threads.
| -rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 35 | ||||
| -rw-r--r-- | indra/llwebrtc/llwebrtc.h | 1 | ||||
| -rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 129 | ||||
| -rw-r--r-- | indra/newview/llvoicewebrtc.h | 13 | 
4 files changed, 126 insertions, 52 deletions
| diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index e7a9072b2e..c2631b2ea3 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -389,6 +389,36 @@ void LLWebRTCImpl::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGath  void LLWebRTCImpl::OnConnectionChange(webrtc::PeerConnectionInterface::PeerConnectionState new_state)  {      RTC_LOG(LS_ERROR) << __FUNCTION__ << " Peer Connection State Change " << new_state; + +    switch (new_state) +    { +        case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected: +        { +            if (new_state == webrtc::PeerConnectionInterface::PeerConnectionState::kConnected) +            { +                for (auto &observer : mSignalingObserverList) +                { +                    observer->OnAudioEstablished(this); +                } +            } +            break; +        } +        case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected: +        { +            if (new_state == webrtc::PeerConnectionInterface::PeerConnectionState::kConnected) +            { +                for (auto &observer : mSignalingObserverList) +                { +                    observer->OnRenegotiationNeeded(); +                } +            } +            break; +        } +        default: +        { +            break; +        } +    }  }  void LLWebRTCImpl::OnIceCandidate(const webrtc::IceCandidateInterface *candidate) @@ -447,10 +477,6 @@ void LLWebRTCImpl::OnSetRemoteDescriptionComplete(webrtc::RTCError error)          RTC_LOG(LS_ERROR) << ToString(error.type()) << ": " << error.message();          return;      } -    for (auto &observer : mSignalingObserverList) -    { -        observer->OnAudioEstablished(this); -    }  }  // @@ -467,6 +493,7 @@ void LLWebRTCImpl::OnSetLocalDescriptionComplete(webrtc::RTCError error)      auto        desc = mPeerConnection->pending_local_description();      std::string sdp;      desc->ToString(&sdp); +    RTC_LOG(LS_INFO) << __FUNCTION__ << " Local SDP: " << sdp;      for (auto &observer : mSignalingObserverList)      {          observer->OnOfferAvailable(sdp); diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h index cb639ee116..acc3665e95 100644 --- a/indra/llwebrtc/llwebrtc.h +++ b/indra/llwebrtc/llwebrtc.h @@ -106,6 +106,7 @@ class LLWebRTCSignalingObserver      virtual void OnIceGatheringState(IceGatheringState state) = 0;      virtual void OnIceCandidate(const LLWebRTCIceCandidate& candidate) = 0;      virtual void OnOfferAvailable(const std::string& sdp) = 0; +    virtual void OnRenegotiationNeeded() = 0;      virtual void OnAudioEstablished(LLWebRTCAudioInterface *audio_interface) = 0;  }; diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 5fcfc969b5..d79b11f1da 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -603,7 +603,7 @@ void LLWebRTCVoiceClient::voiceControlStateMachine()      U32 retry = 0; -    mVoiceControlState = VOICE_STATE_TP_WAIT; +    setVoiceControlState(VOICE_STATE_TP_WAIT);      do      { @@ -617,7 +617,7 @@ void LLWebRTCVoiceClient::voiceControlStateMachine()  		processIceUpdates(); -        switch (mVoiceControlState) +        switch (getVoiceControlState())          {          case VOICE_STATE_TP_WAIT:              // starting point for voice @@ -628,37 +628,44 @@ void LLWebRTCVoiceClient::voiceControlStateMachine()              }              else              { -                mVoiceControlState = VOICE_STATE_START_SESSION; +                setVoiceControlState(VOICE_STATE_START_SESSION);              }              break;          case VOICE_STATE_START_SESSION:              if (establishVoiceConnection())              { -                mVoiceControlState = VOICE_STATE_WAIT_FOR_SESSION_START; +                setVoiceControlState(VOICE_STATE_WAIT_FOR_SESSION_START);              }              else              { -                mVoiceControlState = VOICE_STATE_SESSION_RETRY; +                setVoiceControlState(VOICE_STATE_SESSION_RETRY);              }              break;          case VOICE_STATE_WAIT_FOR_SESSION_START: -            llcoro::suspendUntilTimeout(1.0); -            if (!mChannelSDP.empty())   			{ -                mVoiceControlState = VOICE_STATE_PROVISION_ACCOUNT; +				llcoro::suspendUntilTimeout(1.0); +				std::string channel_sdp; +				{ +					LLMutexLock lock(&mVoiceStateMutex); +					channel_sdp = mChannelSDP; +				} +				if (!channel_sdp.empty() && getVoiceControlState() != VOICE_STATE_SESSION_RETRY) +				{ +					setVoiceControlState(VOICE_STATE_PROVISION_ACCOUNT); +				} +				break;  			} -            break; -          case VOICE_STATE_PROVISION_ACCOUNT: -            if (!provisionVoiceAccount()) +			// getVoiceControlState() can change while provisionVoiceAccount is happening +            if (!provisionVoiceAccount() && getVoiceControlState() == VOICE_STATE_SESSION_RETRY)              { -                mVoiceControlState = VOICE_STATE_SESSION_RETRY; +                setVoiceControlState(VOICE_STATE_SESSION_RETRY);              }              else   			{ -                mVoiceControlState = VOICE_STATE_SESSION_PROVISION_WAIT; +                setVoiceControlState(VOICE_STATE_SESSION_PROVISION_WAIT);  			}              break;          case VOICE_STATE_SESSION_PROVISION_WAIT: @@ -685,11 +692,11 @@ void LLWebRTCVoiceClient::voiceControlStateMachine()                      current_delay++;                      llcoro::suspendUntilTimeout(1.f);                  } -                mVoiceControlState = VOICE_STATE_WAIT_FOR_EXIT; +                setVoiceControlState(VOICE_STATE_WAIT_FOR_EXIT);              }              else              { -                mVoiceControlState = VOICE_STATE_DONE; +                setVoiceControlState(VOICE_STATE_DONE);              }              break; @@ -700,38 +707,43 @@ void LLWebRTCVoiceClient::voiceControlStateMachine()                      performMicTuning();                  } -                mVoiceControlState = VOICE_STATE_WAIT_FOR_CHANNEL; +                setVoiceControlState(VOICE_STATE_WAIT_FOR_CHANNEL);              }              break;          case VOICE_STATE_WAIT_FOR_CHANNEL: -            waitForChannel(); // todo: split into more states like login/fonts -            mVoiceControlState = VOICE_STATE_DISCONNECT; +            { +                if (!waitForChannel())  // todo: split into more states like login/fonts +                { +                    setVoiceControlState(VOICE_STATE_DISCONNECT); +                } +				// on true, it's a retry, so let the state stand. +            }              break;          case VOICE_STATE_DISCONNECT:              LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;              endAndDisconnectSession();              retry = 0; // Connected without issues -            mVoiceControlState = VOICE_STATE_WAIT_FOR_EXIT; +            setVoiceControlState(VOICE_STATE_WAIT_FOR_EXIT);              break;          case VOICE_STATE_WAIT_FOR_EXIT:              if (mRelogRequested && mVoiceEnabled)              {                  LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL; -                mVoiceControlState = VOICE_STATE_TP_WAIT; +                setVoiceControlState(VOICE_STATE_TP_WAIT);              }              else              { -                mVoiceControlState = VOICE_STATE_DONE; +                setVoiceControlState(VOICE_STATE_DONE);              }              break;          case VOICE_STATE_DONE:              break;          } -    } while (mVoiceControlState > 0); +    } while (getVoiceControlState() > 0);      if (sShuttingDown)      { @@ -792,7 +804,10 @@ bool LLWebRTCVoiceClient::provisionVoiceAccount()      LLSD body;      LLSD jsep;      jsep["type"] = "offer"; -    jsep["sdp"]  = mChannelSDP; +    { +        LLMutexLock lock(&mVoiceStateMutex); +        jsep["sdp"] = mChannelSDP; +    }      body["jsep"] = jsep;      LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( @@ -806,7 +821,6 @@ bool LLWebRTCVoiceClient::provisionVoiceAccount()  void LLWebRTCVoiceClient::OnVoiceAccountProvisioned(const LLSD& result)  { -    mVoiceControlState = VOICE_STATE_SESSION_ESTABLISHED;      LLVoiceWebRTCStats::getInstance()->provisionAttemptEnd(true);      std::string channelSDP;      if (result.has("jsep") &&  @@ -825,6 +839,7 @@ void LLWebRTCVoiceClient::OnVoiceAccountProvisioned(const LLSD& result)                         << (voicePassword.empty() ? "not set" : "set") << " channel sdp " << channelSDP << LL_ENDL;      setLoginInfo(voiceUserName, voicePassword, channelSDP); +    setVoiceControlState(VOICE_STATE_SESSION_ESTABLISHED);  }  void LLWebRTCVoiceClient::OnVoiceAccountProvisionFailure(std::string url, int retries, LLSD body, const LLSD& result) @@ -1326,6 +1341,11 @@ bool LLWebRTCVoiceClient::waitForChannel()              return false;          } +		if (getVoiceControlState() == VOICE_STATE_SESSION_RETRY)  +		{ +            return true; +		} +  		processIceUpdates();          switch (state)          { @@ -2759,14 +2779,16 @@ void LLWebRTCVoiceClient::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObserve  {      LL_INFOS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL; -	if (state != llwebrtc::LLWebRTCSignalingObserver::IceGatheringState::ICE_GATHERING_COMPLETE)  -	{  -		return;  +	if (state == llwebrtc::LLWebRTCSignalingObserver::IceGatheringState::ICE_GATHERING_COMPLETE)  +	{ +        LLMutexLock lock(&mVoiceStateMutex); +        mIceCompleted = true;  	} -    mIceCompleted = true;  } -void LLWebRTCVoiceClient::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate &candidate) {  +void LLWebRTCVoiceClient::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate &candidate) +{ +    LLMutexLock lock(&mVoiceStateMutex);  	mIceCandidates.push_back(candidate);   } @@ -2795,31 +2817,35 @@ void LLWebRTCVoiceClient::processIceUpdates()      LLCore::HttpOptions::ptr_t                  httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);      LLSD body; -    if (mIceCandidates.size())      { -        LLSD body; +        LLMutexLock lock(&mVoiceStateMutex); -        for (auto &ice_candidate : mIceCandidates) +        if (mIceCandidates.size()) +        { +            LLSD body; + +            for (auto &ice_candidate : mIceCandidates) +            { +                LLSD body_candidate; +                body_candidate["sdpMid"]        = ice_candidate.sdp_mid; +                body_candidate["sdpMLineIndex"] = ice_candidate.mline_index; +                body_candidate["candidate"]     = ice_candidate.candidate; +                body["candidates"].append(body_candidate); +            } +            mIceCandidates.clear(); +        } +        else if (mIceCompleted)          {              LLSD body_candidate; -            body_candidate["sdpMid"]        = ice_candidate.sdp_mid; -            body_candidate["sdpMLineIndex"] = ice_candidate.mline_index; -            body_candidate["candidate"]     = ice_candidate.candidate; -            body["candidates"].append(body_candidate); +            body_candidate["completed"] = true; +            body["candidate"]           = body_candidate; +            mIceCompleted               = false; +        } +        else +        { +            return;          } -        mIceCandidates.clear(); -    } -    else if (mIceCompleted) -    { -        LLSD body_candidate; -        body_candidate["completed"] = true; -        body["candidate"]           = body_candidate; -        mIceCompleted = false;      } -    else -	{  -		return; -	}      LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url,                                    LLCore::HttpRequest::DEFAULT_POLICY_ID,                                    body, @@ -2862,6 +2888,7 @@ void LLWebRTCVoiceClient::onIceUpdateError(int retries, std::string url, LLSD bo  void LLWebRTCVoiceClient::OnOfferAvailable(const std::string &sdp)   {      LL_INFOS("Voice") << "On Offer Available." << LL_ENDL; +    LLMutexLock lock(&mVoiceStateMutex);      mChannelSDP = sdp;  } @@ -2872,6 +2899,12 @@ void LLWebRTCVoiceClient::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *      audio_interface->setMute(true);  } +void LLWebRTCVoiceClient::OnRenegotiationNeeded() +{ +    LL_INFOS("Voice") << "On Renegotiation Needed." << LL_ENDL; +    setVoiceControlState(VOICE_STATE_SESSION_RETRY); +} +  /////////////////////////////  // Response/Event handlers diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index 22c022ffdb..061e00581e 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -252,6 +252,7 @@ public:      void OnIceGatheringState(IceGatheringState state) override;      void OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate &candidate) override;      void OnOfferAvailable(const std::string &sdp) override; +    void OnRenegotiationNeeded() override;      void OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *audio_interface) override;      //@} @@ -651,7 +652,19 @@ private:      //---      void voiceControlCoro();      void voiceControlStateMachine(); +      int  mVoiceControlState; +    LLMutex mVoiceStateMutex; +	void setVoiceControlState(int new_voice_control_state) +	{  +		LLMutexLock lock(&mVoiceStateMutex); +		mVoiceControlState = new_voice_control_state;  +	} +    int  getVoiceControlState() +	{  +		LLMutexLock lock(&mVoiceStateMutex); +		return mVoiceControlState;  +	}      bool endAndDisconnectSession(); | 
