diff options
author | Roxie Linden <roxie@lindenlab.com> | 2024-03-19 15:23:43 -0700 |
---|---|---|
committer | Roxie Linden <roxie@lindenlab.com> | 2024-03-19 15:23:43 -0700 |
commit | 5bc92b8031e9a6258bab8b24d42090a495cec6e5 (patch) | |
tree | 07eb27fc3411a0cb32f6245bfea9d7cd6d1f889c | |
parent | e4dee511cab0a98e802e2c0cc12b3d8b9b90a8df (diff) |
Simplify workqueue calls. Fix issue with webrtc blocking on destruction.
-rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 62 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc.h | 3 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 16 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 358 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.h | 21 |
5 files changed, 198 insertions, 262 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 6400f807fd..283b94dd3c 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -562,8 +562,10 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn // Most peer connection (signaling) happens on // the signaling thread. -LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() : +LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() : mWebRTCImpl(nullptr), + mClosing(false), + mPeerConnection(nullptr), mMute(false), mAnswerReceived(false) { @@ -580,13 +582,24 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl) } void LLWebRTCPeerConnectionImpl::terminate() { + rtc::scoped_refptr<webrtc::PeerConnectionInterface> connection; + mPeerConnection.swap(connection); + rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel; + mDataChannel.swap(dataChannel); + rtc::scoped_refptr<webrtc::MediaStreamInterface> localStream; + mLocalStream.swap(localStream); + mWebRTCImpl->PostSignalingTask( - [this]() + [=]() { - if (mPeerConnection) + if (connection) + { + connection->Close(); + } + if (dataChannel) { - mPeerConnection->Close(); - mPeerConnection = nullptr; + dataChannel->UnregisterObserver(); + dataChannel->Close(); } }); } @@ -710,24 +723,9 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection() bool LLWebRTCPeerConnectionImpl::shutdownConnection() { - if (mPeerConnection) - { - mWebRTCImpl->PostSignalingTask( - [this]() - { - if (mPeerConnection) - { - mPeerConnection->Close(); - mPeerConnection = nullptr; - } - for (auto &observer : mSignalingObserverList) - { - observer->OnPeerConnectionShutdown(); - } - }); - return true; - } - return false; + mClosing = true; + terminate(); + return true; } void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable) @@ -1057,14 +1055,16 @@ void LLWebRTCPeerConnectionImpl::OnSuccess(webrtc::SessionDescriptionInterface * } RTC_LOG(LS_INFO) << __FUNCTION__ << " Local SDP: " << sdp_mangled_stream.str(); - + std::string mangled_sdp = sdp_mangled_stream.str(); for (auto &observer : mSignalingObserverList) { - observer->OnOfferAvailable(sdp_mangled_stream.str()); + observer->OnOfferAvailable(mangled_sdp); } + + mPeerConnection->SetLocalDescription(std::unique_ptr<webrtc::SessionDescriptionInterface>( + webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, mangled_sdp)), + rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface>(this)); - mPeerConnection->SetLocalDescription(std::unique_ptr<webrtc::SessionDescriptionInterface>(webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp_mangled_stream.str())), - rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface>(this)); } void LLWebRTCPeerConnectionImpl::OnFailure(webrtc::RTCError error) @@ -1135,6 +1135,14 @@ void LLWebRTCPeerConnectionImpl::OnStateChange() break; case webrtc::DataChannelInterface::kClosed: RTC_LOG(LS_INFO) << __FUNCTION__ << " Data Channel State closed"; + // if the data channel is up, we need to shut it down, holding off + // on termination of the peer connection until it's been closed. + if (mClosing) + { + // a close was requested, and the data channel has closed, + // so go ahead and call shutdownConnection again to clean up. + shutdownConnection(); + } break; default: break; diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h index dab7774499..be2e5cdf68 100644 --- a/indra/llwebrtc/llwebrtc.h +++ b/indra/llwebrtc/llwebrtc.h @@ -192,9 +192,6 @@ class LLWebRTCSignalingObserver // Called when the data channel has been established and data // transfer can begin. virtual void OnDataChannelReady(LLWebRTCDataInterface *data_interface) = 0; - - // Called when a peer connection has finished shutting down. - virtual void OnPeerConnectionShutdown() = 0; }; diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index 1f696e8c66..38810a29b5 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -346,21 +346,23 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, LLWebRTCImpl * mWebRTCImpl; + bool mClosing; + rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory; - bool mMute; + bool mMute; // signaling - std::vector<LLWebRTCSignalingObserver *> mSignalingObserverList; + std::vector<LLWebRTCSignalingObserver *> mSignalingObserverList; std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> mCachedIceCandidates; - bool mAnswerReceived; + bool mAnswerReceived; - rtc::scoped_refptr<webrtc::PeerConnectionInterface> mPeerConnection; - rtc::scoped_refptr<webrtc::MediaStreamInterface> mLocalStream; + rtc::scoped_refptr<webrtc::PeerConnectionInterface> mPeerConnection; + rtc::scoped_refptr<webrtc::MediaStreamInterface> mLocalStream; // data - std::vector<LLWebRTCDataObserver *> mDataObserverList; - rtc::scoped_refptr<webrtc::DataChannelInterface> mDataChannel; + std::vector<LLWebRTCDataObserver *> mDataObserverList; + rtc::scoped_refptr<webrtc::DataChannelInterface> mDataChannel; }; } diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 1441e4e305..6aab67ca63 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -2043,38 +2043,31 @@ LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection() // callback from llwebrtc void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state) { - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnIceGatheringStateImpl(state); }); -} - -void LLVoiceWebRTCConnection::OnIceGatheringStateImpl(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state) -{ - LL_DEBUGS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL; + LL::WorkQueue::postMaybe(mMainQueue, + [=] { + LL_DEBUGS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL; - switch (state) - { - case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_COMPLETE: - { - mIceCompleted = true; - break; - } - case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_NEW: - { - mIceCompleted = false; - } - default: - break; - } + switch (state) + { + case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_COMPLETE: + { + mIceCompleted = true; + break; + } + case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_NEW: + { + mIceCompleted = false; + } + default: + break; + } + }); } // callback from llwebrtc void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate& candidate) { - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnIceCandidateImpl(candidate); }); -} - -void LLVoiceWebRTCConnection::OnIceCandidateImpl(const llwebrtc::LLWebRTCIceCandidate &candidate) -{ - mIceCandidates.push_back(candidate); + LL::WorkQueue::postMaybe(mMainQueue, [=] { mIceCandidates.push_back(candidate); }); } void LLVoiceWebRTCConnection::onIceUpdateComplete(bool ice_completed, const LLSD &result) @@ -2205,37 +2198,31 @@ void LLVoiceWebRTCConnection::processIceUpdates() // and is passed to the simulator via a CAP, which then passes // it on to the Secondlife WebRTC server. -// callback from llwebrtc -void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp) -{ - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnOfferAvailableImpl(sdp); }); -} - // // The LLWebRTCVoiceConnection object will not be deleted // before the webrtc connection itself is shut down, so // we shouldn't be getting this callback on a nonexistant // this pointer. -void LLVoiceWebRTCConnection::OnOfferAvailableImpl(const std::string &sdp) -{ - if (mShutDown) - { - return; - } - LL_DEBUGS("Voice") << "On Offer Available." << LL_ENDL; - mChannelSDP = sdp; - if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_SESSION_START) - { - mVoiceConnectionState = VOICE_STATE_REQUEST_CONNECTION; - } -} // callback from llwebrtc -void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface) +void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp) { - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnAudioEstablishedImpl(audio_interface); }); + LL::WorkQueue::postMaybe(mMainQueue, + [=] { + if (mShutDown) + { + return; + } + LL_DEBUGS("Voice") << "On Offer Available." << LL_ENDL; + mChannelSDP = sdp; + if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_SESSION_START) + { + mVoiceConnectionState = VOICE_STATE_REQUEST_CONNECTION; + } + }); } + // // The LLWebRTCVoiceConnection object will not be deleted // before the webrtc connection itself is shut down, so @@ -2243,48 +2230,42 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac // this pointer. // nor should audio_interface be invalid if the LLWebRTCVoiceConnection // is shut down. -void LLVoiceWebRTCConnection::OnAudioEstablishedImpl(llwebrtc::LLWebRTCAudioInterface *audio_interface) -{ - if (mShutDown) - { - return; - } - LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL; - mWebRTCAudioInterface = audio_interface; - setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED); -} // callback from llwebrtc -void LLVoiceWebRTCConnection::OnRenegotiationNeeded() +void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface) { - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnRenegotiationNeededImpl(); }); + LL::WorkQueue::postMaybe(mMainQueue, + [=] { + if (mShutDown) + { + return; + } + LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL; + mWebRTCAudioInterface = audio_interface; + setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED); + }); } + // // The LLWebRTCVoiceConnection object will not be deleted // before the webrtc connection itself is shut down, so // we shouldn't be getting this callback on a nonexistant // this pointer. -void LLVoiceWebRTCConnection::OnRenegotiationNeededImpl() -{ - LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL; - if (!mShutDown) - { - setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); - } -} // callback from llwebrtc -void LLVoiceWebRTCConnection::OnPeerConnectionShutdown() +void LLVoiceWebRTCConnection::OnRenegotiationNeeded() { - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnPeerConnectionShutdownImpl(); }); + LL::WorkQueue::postMaybe(mMainQueue, + [=] { + LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL; + if (!mShutDown) + { + setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + } + }); } -void LLVoiceWebRTCConnection::OnPeerConnectionShutdownImpl() -{ - setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); - mOutstandingRequests--; // shut down is an async call which is handled on a webrtc thread. -} void LLVoiceWebRTCConnection::setMuteMic(bool muted) { @@ -2354,7 +2335,7 @@ void LLVoiceWebRTCConnection::sendData(const std::string &data) // Tell the simulator that we're shutting down a voice connection. // The simulator will pass this on to the Secondlife WebRTC server. -bool LLVoiceWebRTCConnection::breakVoiceConnection(bool corowait) +void LLVoiceWebRTCConnection::breakVoiceConnection() { LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL; if (mWebRTCDataInterface) @@ -2367,96 +2348,53 @@ bool LLVoiceWebRTCConnection::breakVoiceConnection(bool corowait) if (!regionp || !regionp->capabilitiesReceived()) { LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL; - setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); - return false; + return; } std::string url = regionp->getCapability("ProvisionVoiceAccountRequest"); if (url.empty()) { - return false; + return; } LL_DEBUGS("Voice") << "region ready for voice break; url=" << url << LL_ENDL; - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("parcelVoiceInfoRequest", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLVoiceWebRTCStats::getInstance()->provisionAttemptStart(); LLSD body; body["logout"] = TRUE; body["viewer_session"] = mViewerSession; body["voice_server_type"] = REPORTED_VOICE_SERVER_TYPE; - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( - url, - LLCore::HttpRequest::DEFAULT_POLICY_ID, - body, - boost::bind(&LLVoiceWebRTCSpatialConnection::OnVoiceDisconnectionRequestSuccess, this, _1), - boost::bind(&LLVoiceWebRTCSpatialConnection::OnVoiceDisconnectionRequestFailure, this, url, 3, body, _1)); - setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT); - mOutstandingRequests++; - return true; -} + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter( + new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::breakVoiceConnection", + LLCore::HttpRequest::DEFAULT_POLICY_ID)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); -void LLVoiceWebRTCConnection::OnVoiceDisconnectionRequestSuccess(const LLSD &result) -{ - mOutstandingRequests--; - if (LLWebRTCVoiceClient::isShuttingDown()) - { - return; - } + httpOpts->setWantHeaders(true); - if (mWebRTCPeerConnectionInterface) - { - if (mWebRTCPeerConnectionInterface->shutdownConnection()) - { - mOutstandingRequests++; - } - } - else - { - setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); - } -} + mOutstandingRequests++; + setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT); + + // tell the server to shut down the connection as a courtesy. + // shutdownConnection will drop the WebRTC connection which will + // also shut things down. + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts); -void LLVoiceWebRTCConnection::OnVoiceDisconnectionRequestFailure(std::string url, int retries, LLSD body, const LLSD &result) -{ - if (LLWebRTCVoiceClient::isShuttingDown()) - { - mOutstandingRequests--; - return; - } - if (retries >= 0) - { - // retry a few times. - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( - url, - LLCore::HttpRequest::DEFAULT_POLICY_ID, - body, - boost::bind(&LLVoiceWebRTCSpatialConnection::OnVoiceDisconnectionRequestSuccess, this, _1), - boost::bind(&LLVoiceWebRTCSpatialConnection::OnVoiceDisconnectionRequestFailure, this, url, retries - 1, body, _1)); - return; - } if (mWebRTCPeerConnectionInterface) { - mOutstandingRequests++; mWebRTCPeerConnectionInterface->shutdownConnection(); } - else - { - setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); - } + setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); + mOutstandingRequests--; } - // Tell the simulator to tell the Secondlife WebRTC server that we want a voice // connection. The SDP is sent up as part of this, and the simulator will respond // with an 'answer' which is in the form of another SDP. The webrtc library // will use the offer and answer to negotiate the session. -bool LLVoiceWebRTCSpatialConnection::requestVoiceConnection() +void LLVoiceWebRTCSpatialConnection::requestVoiceConnection() { LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID); @@ -2464,13 +2402,15 @@ bool LLVoiceWebRTCSpatialConnection::requestVoiceConnection() if (!regionp || !regionp->capabilitiesReceived()) { LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL; - return false; + setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + return; } std::string url = regionp->getCapability("ProvisionVoiceAccountRequest"); if (url.empty()) { - return false; + setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + return; } LL_DEBUGS("Voice") << "region ready for voice provisioning; url=" << url << LL_ENDL; @@ -2489,27 +2429,42 @@ bool LLVoiceWebRTCSpatialConnection::requestVoiceConnection() } body["channel_type"] = "local"; body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter( + new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::requestVoiceConnection", + LLCore::HttpRequest::DEFAULT_POLICY_ID)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( - url, - LLCore::HttpRequest::DEFAULT_POLICY_ID, - body, - boost::bind(&LLVoiceWebRTCSpatialConnection::OnVoiceConnectionRequestSuccess, this, _1), - boost::bind(&LLVoiceWebRTCSpatialConnection::OnVoiceConnectionRequestFailure, this, url, 3, body, _1)); + httpOpts->setWantHeaders(true); mOutstandingRequests++; - return true; + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + } + else + { + OnVoiceConnectionRequestSuccess(result); + } + mOutstandingRequests--; } void LLVoiceWebRTCConnection::OnVoiceConnectionRequestSuccess(const LLSD &result) { - mOutstandingRequests--; if (LLWebRTCVoiceClient::isShuttingDown()) { return; } LLVoiceWebRTCStats::getInstance()->provisionAttemptEnd(true); - if (result.has("viewer_session") && result.has("jsep") && result["jsep"].has("type") && result["jsep"]["type"] == "answer" && + if (result.has("viewer_session") && + result.has("jsep") && + result["jsep"].has("type") && + result["jsep"]["type"] == "answer" && result["jsep"].has("sdp")) { mRemoteChannelSDP = result["jsep"]["sdp"].asString(); @@ -2524,35 +2479,9 @@ void LLVoiceWebRTCConnection::OnVoiceConnectionRequestSuccess(const LLSD &result LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response" << " channel sdp " << mRemoteChannelSDP << LL_ENDL; - mWebRTCPeerConnectionInterface->AnswerAvailable(mRemoteChannelSDP); } - -void LLVoiceWebRTCConnection::OnVoiceConnectionRequestFailure(std::string url, int retries, LLSD body, const LLSD &result) -{ - if (LLWebRTCVoiceClient::isShuttingDown()) - { - mOutstandingRequests--; - return; - } - if (retries >= 0) - { - LL_WARNS("Voice") << "Failure connecting to voice, retrying." << body << " RESULT: " << result << LL_ENDL; - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( - url, - LLCore::HttpRequest::DEFAULT_POLICY_ID, - body, - boost::bind(&LLVoiceWebRTCConnection::OnVoiceConnectionRequestSuccess, this, _1), - boost::bind(&LLVoiceWebRTCConnection::OnVoiceConnectionRequestFailure, this, url, retries - 1, body, _1)); - return; - } - LL_WARNS("Voice") << "Unable to connect voice." << body << " RESULT: " << result << LL_ENDL; - setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); - mOutstandingRequests--; -} - - // Primary state machine for negotiating a single voice connection to the // Secondlife WebRTC server. bool LLVoiceWebRTCConnection::connectionStateMachine() @@ -2599,14 +2528,9 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() // Ask the sim to ask the Secondlife WebRTC server for a connection to // a given voice channel. On completion, we'll move on to the // VOICE_STATE_SESSION_ESTABLISHED via a callback on a webrtc thread. - if (!requestVoiceConnection()) - { - setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); - } - else - { - setVoiceConnectionState(VOICE_STATE_CONNECTION_WAIT); - } + setVoiceConnectionState(VOICE_STATE_CONNECTION_WAIT); + LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::requestVoiceConnectionCoro", + boost::bind(&LLVoiceWebRTCConnection::requestVoiceConnectionCoro, this)); break; case VOICE_STATE_CONNECTION_WAIT: @@ -2680,7 +2604,8 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() break; case VOICE_STATE_DISCONNECT: - breakVoiceConnection(true); + LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnection", + boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnection, this)); break; case VOICE_STATE_WAIT_FOR_EXIT: @@ -2732,7 +2657,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() // llwebrtc callback void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binary) { - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnDataReceivedImpl(data, binary); }); + LL::WorkQueue::postMaybe(mMainQueue, [=] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); }); } // @@ -2853,12 +2778,6 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b } } -// llwebrtc callback -void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface) -{ - LL::WorkQueue::postMaybe(mMainQueue, [=] { OnDataChannelReadyImpl(data_interface); }); -} - // // The LLWebRTCVoiceConnection object will not be deleted // before the webrtc connection itself is shut down, so @@ -2866,18 +2785,23 @@ void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface // this pointer. // nor should data_interface be invalid if the LLWebRTCVoiceConnection // is shut down. -void LLVoiceWebRTCConnection::OnDataChannelReadyImpl(llwebrtc::LLWebRTCDataInterface *data_interface) + +// llwebrtc callback +void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface) { - if (mShutDown) - { - return; - } + LL::WorkQueue::postMaybe(mMainQueue, + [=] { + if (mShutDown) + { + return; + } - if (data_interface) - { - mWebRTCDataInterface = data_interface; - mWebRTCDataInterface->setDataObserver(this); - } + if (data_interface) + { + mWebRTCDataInterface = data_interface; + mWebRTCDataInterface->setDataObserver(this); + } + }); } // tell the Secondlife WebRTC server that @@ -2974,7 +2898,7 @@ LLVoiceWebRTCAdHocConnection::~LLVoiceWebRTCAdHocConnection() // as they go to a different set of Secondlife WebRTC servers. // They also require credentials for the given channels. // So, we have a separate requestVoiceConnection call. -bool LLVoiceWebRTCAdHocConnection::requestVoiceConnection() +void LLVoiceWebRTCAdHocConnection::requestVoiceConnection() { LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID); @@ -2982,13 +2906,15 @@ bool LLVoiceWebRTCAdHocConnection::requestVoiceConnection() if (!regionp || !regionp->capabilitiesReceived()) { LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL; - return false; + setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + return; } std::string url = regionp->getCapability("ProvisionVoiceAccountRequest"); if (url.empty()) { - return false; + setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + return; } LLVoiceWebRTCStats::getInstance()->provisionAttemptStart(); @@ -3004,12 +2930,26 @@ bool LLVoiceWebRTCAdHocConnection::requestVoiceConnection() body["channel_type"] = "multiagent"; body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( - url, - LLCore::HttpRequest::DEFAULT_POLICY_ID, - body, - boost::bind(&LLVoiceWebRTCAdHocConnection::OnVoiceConnectionRequestSuccess, this, _1), - boost::bind(&LLVoiceWebRTCAdHocConnection::OnVoiceConnectionRequestFailure, this, url, 3, body, _1)); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter( + new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::requestVoiceConnection", + LLCore::HttpRequest::DEFAULT_POLICY_ID)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + + httpOpts->setWantHeaders(true); mOutstandingRequests++; - return true; + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + } + else + { + OnVoiceConnectionRequestSuccess(result); + } + mOutstandingRequests--; } diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index b0c214dfd5..21fc79420b 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -588,16 +588,8 @@ class LLVoiceWebRTCConnection : void OnOfferAvailable(const std::string &sdp) override; void OnRenegotiationNeeded() override; void OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *audio_interface) override; - void OnPeerConnectionShutdown() override; //@} - void OnIceGatheringStateImpl(EIceGatheringState state); - void OnIceCandidateImpl(const llwebrtc::LLWebRTCIceCandidate &candidate); - void OnOfferAvailableImpl(const std::string &sdp); - void OnRenegotiationNeededImpl(); - void OnAudioEstablishedImpl(llwebrtc::LLWebRTCAudioInterface *audio_interface); - void OnPeerConnectionShutdownImpl(); - ///////////////////////// /// @name Data Notification /// LLWebRTCDataObserver @@ -607,7 +599,6 @@ class LLVoiceWebRTCConnection : //@} void OnDataReceivedImpl(const std::string &data, bool binary); - void OnDataChannelReadyImpl(llwebrtc::LLWebRTCDataInterface *data_interface); void sendJoin(); void sendData(const std::string &data); @@ -635,7 +626,6 @@ class LLVoiceWebRTCConnection : } void OnVoiceConnectionRequestSuccess(const LLSD &body); - void OnVoiceConnectionRequestFailure(std::string url, int retries, LLSD body, const LLSD &result); protected: typedef enum e_voice_connection_state @@ -680,11 +670,10 @@ class LLVoiceWebRTCConnection : return mVoiceConnectionState; } - virtual bool requestVoiceConnection() = 0; + virtual void requestVoiceConnection() = 0; + void requestVoiceConnectionCoro() { requestVoiceConnection(); } - bool breakVoiceConnection(bool wait); - void OnVoiceDisconnectionRequestSuccess(const LLSD &body); - void OnVoiceDisconnectionRequestFailure(std::string url, int retries, LLSD body, const LLSD &result); + void breakVoiceConnection(); LLUUID mRegionID; LLUUID mViewerSession; @@ -731,7 +720,7 @@ class LLVoiceWebRTCSpatialConnection : protected: - bool requestVoiceConnection() override; + void requestVoiceConnection() override; S32 mParcelLocalID; }; @@ -746,7 +735,7 @@ class LLVoiceWebRTCAdHocConnection : public LLVoiceWebRTCConnection bool isSpatial() override { return false; } protected: - bool requestVoiceConnection() override; + void requestVoiceConnection() override; std::string mCredentials; }; |