From e4dee511cab0a98e802e2c0cc12b3d8b9b90a8df Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Mon, 18 Mar 2024 17:47:56 -0700 Subject: Use LL::WorkQueue to handle transitions from llwebrtc threads to the main thread --- indra/llwebrtc/llwebrtc.cpp | 2 +- indra/newview/llvoicewebrtc.cpp | 153 +++++++++++++++++++++++++++++++++------- indra/newview/llvoicewebrtc.h | 26 ++++--- 3 files changed, 144 insertions(+), 37 deletions(-) diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index b7501bd0e0..6400f807fd 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -580,7 +580,7 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl) } void LLWebRTCPeerConnectionImpl::terminate() { - mWebRTCImpl->SignalingBlockingCall( + mWebRTCImpl->PostSignalingTask( [this]() { if (mPeerConnection) diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index cae7154bc2..1441e4e305 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -1,5 +1,5 @@ /** - * @file LLWebRTCVoiceClient.cpp + * @file llvoicewebrtc.cpp * @brief Implementation of LLWebRTCVoiceClient class which is the interface to the voice client process. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ @@ -585,8 +585,19 @@ void LLWebRTCVoiceClient::setDevicesListUpdated(bool state) mDevicesListUpdated = state; } -void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices, - const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices) +// the singleton 'this' pointer will outlive the work queue. +void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceList& render_devices, + const llwebrtc::LLWebRTCVoiceDeviceList& capture_devices) +{ + LL::WorkQueue::postMaybe(mMainQueue, + [=] + { + OnDevicesChangedImpl(render_devices, capture_devices); + }); +} + +void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices, + const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices) { std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice"); std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice"); @@ -1412,6 +1423,7 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled) updatePosition(); if (!mIsCoroutineActive) { + mMainQueue = LL::WorkQueue::getInstance("mainloop"); LLCoros::instance().launch("LLWebRTCVoiceClient::voiceConnectionCoro", boost::bind(&LLWebRTCVoiceClient::voiceConnectionCoro, LLWebRTCVoiceClient::getInstance())); } @@ -2000,6 +2012,7 @@ LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID ®ionID, const s mWebRTCPeerConnectionInterface = llwebrtc::newPeerConnection(); mWebRTCPeerConnectionInterface->setSignalingObserver(this); + mMainQueue = LL::WorkQueue::getInstance("mainloop"); } LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection() @@ -2026,7 +2039,14 @@ LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection() // negotiated, updates about the best connectivity paths may trickle in. These need to be // sent to the Secondlife WebRTC server via the simulator so that both sides have a clear // view of the network environment. + +// 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; @@ -2034,13 +2054,11 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs { case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_COMPLETE: { - LLMutexLock lock(&mVoiceStateMutex); mIceCompleted = true; break; } case llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState::ICE_GATHERING_NEW: { - LLMutexLock lock(&mVoiceStateMutex); mIceCompleted = false; } default: @@ -2048,9 +2066,14 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs } } -void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate &candidate) +// callback from llwebrtc +void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate& candidate) +{ + LL::WorkQueue::postMaybe(mMainQueue, [=] { OnIceCandidateImpl(candidate); }); +} + +void LLVoiceWebRTCConnection::OnIceCandidateImpl(const llwebrtc::LLWebRTCIceCandidate &candidate) { - LLMutexLock lock(&mVoiceStateMutex); mIceCandidates.push_back(candidate); } @@ -2182,10 +2205,24 @@ 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; - LLMutexLock lock(&mVoiceStateMutex); mChannelSDP = sdp; if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_SESSION_START) { @@ -2193,15 +2230,42 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp) } } -// Notifications from the webrtc library. -void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *audio_interface) +// callback from llwebrtc +void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface) +{ + LL::WorkQueue::postMaybe(mMainQueue, [=] { OnAudioEstablishedImpl(audio_interface); }); +} + +// +// 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. +// 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() +{ + LL::WorkQueue::postMaybe(mMainQueue, [=] { OnRenegotiationNeededImpl(); }); +} + +// +// 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) @@ -2210,7 +2274,13 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded() } } +// callback from llwebrtc void LLVoiceWebRTCConnection::OnPeerConnectionShutdown() +{ + LL::WorkQueue::postMaybe(mMainQueue, [=] { OnPeerConnectionShutdownImpl(); }); +} + +void LLVoiceWebRTCConnection::OnPeerConnectionShutdownImpl() { setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); mOutstandingRequests--; // shut down is an async call which is handled on a webrtc thread. @@ -2410,7 +2480,6 @@ bool LLVoiceWebRTCSpatialConnection::requestVoiceConnection() LLSD jsep; jsep["type"] = "offer"; { - LLMutexLock lock(&mVoiceStateMutex); jsep["sdp"] = mChannelSDP; } body["jsep"] = jsep; @@ -2620,7 +2689,6 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() case VOICE_STATE_SESSION_EXIT: { { - LLMutexLock lock(&mVoiceStateMutex); if (!mShutDown) { mVoiceConnectionState = VOICE_STATE_START_SESSION; @@ -2649,19 +2717,35 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() } // Data has been received on the webrtc data channel -void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binary) -{ - // incoming data will be a json structure (if it's not binary.) We may pack - // binary for size reasons. Most of the keys in the json objects are - // single or double characters for size reasons. - // The primary element is: - // An object where each key is an agent id. (in the future, we may allow - // integer indices into an agentid list, populated on join commands. For size. - // Each key will point to a json object with keys identifying what's updated. - // 'p' - audio source power (level/volume) (int8 as int) - // 'j' - object of join data (currently only a boolean 'p' marking a primary participant) - // 'l' - boolean, always true if exists. - // 'v' - boolean - voice activity has been detected. +// incoming data will be a json structure (if it's not binary.) We may pack +// binary for size reasons. Most of the keys in the json objects are +// single or double characters for size reasons. +// The primary element is: +// An object where each key is an agent id. (in the future, we may allow +// integer indices into an agentid list, populated on join commands. For size. +// Each key will point to a json object with keys identifying what's updated. +// 'p' - audio source power (level/volume) (int8 as int) +// 'j' - object of join data (currently only a boolean 'p' marking a primary participant) +// 'l' - boolean, always true if exists. +// 'v' - boolean - voice activity has been detected. + +// llwebrtc callback +void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binary) +{ + LL::WorkQueue::postMaybe(mMainQueue, [=] { OnDataReceivedImpl(data, binary); }); +} + +// +// 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::OnDataReceivedImpl(const std::string &data, bool binary) +{ + if (mShutDown) + { + return; + } if (binary) { @@ -2769,8 +2853,26 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binar } } +// 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 +// we shouldn't be getting this callback on a nonexistant +// this pointer. +// nor should data_interface be invalid if the LLWebRTCVoiceConnection +// is shut down. +void LLVoiceWebRTCConnection::OnDataChannelReadyImpl(llwebrtc::LLWebRTCDataInterface *data_interface) +{ + if (mShutDown) + { + return; + } + if (data_interface) { mWebRTCDataInterface = data_interface; @@ -2894,7 +2996,6 @@ bool LLVoiceWebRTCAdHocConnection::requestVoiceConnection() LLSD jsep; jsep["type"] = "offer"; { - LLMutexLock lock(&mVoiceStateMutex); jsep["sdp"] = mChannelSDP; } body["jsep"] = jsep; diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index b26bea27ce..b0c214dfd5 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -225,7 +225,8 @@ public: void OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices, const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices) override; //@} - + void OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDeviceList &render_devices, + const llwebrtc::LLWebRTCVoiceDeviceList &capture_devices); struct participantState { @@ -445,6 +446,8 @@ private: /// Clean up objects created during a voice session. void cleanUp(); + LL::WorkQueue::weak_t mMainQueue; + bool mTuningMode; F32 mTuningMicGain; int mTuningSpeakerVolume; @@ -588,6 +591,13 @@ class LLVoiceWebRTCConnection : 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 @@ -596,6 +606,9 @@ class LLVoiceWebRTCConnection : void OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface) override; //@} + void OnDataReceivedImpl(const std::string &data, bool binary); + void OnDataChannelReadyImpl(llwebrtc::LLWebRTCDataInterface *data_interface); + void sendJoin(); void sendData(const std::string &data); @@ -618,7 +631,6 @@ class LLVoiceWebRTCConnection : void shutDown() { - LLMutexLock lock(&mVoiceStateMutex); mShutDown = true; } @@ -644,11 +656,10 @@ class LLVoiceWebRTCConnection : } EVoiceConnectionState; EVoiceConnectionState mVoiceConnectionState; - LLMutex mVoiceStateMutex; + LL::WorkQueue::weak_t mMainQueue; + void setVoiceConnectionState(EVoiceConnectionState new_voice_connection_state) { - LLMutexLock lock(&mVoiceStateMutex); - if (new_voice_connection_state & VOICE_STATE_SESSION_STOPPING) { // the new state is shutdown or restart. @@ -666,11 +677,6 @@ class LLVoiceWebRTCConnection : } EVoiceConnectionState getVoiceConnectionState() { - if (mVoiceStateMutex.isLocked()) - { - LL_WARNS("Voice") << "LOCKED." << LL_ENDL; - } - LLMutexLock lock(&mVoiceStateMutex); return mVoiceConnectionState; } -- cgit v1.2.3 From 5bc92b8031e9a6258bab8b24d42090a495cec6e5 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Tue, 19 Mar 2024 15:23:43 -0700 Subject: Simplify workqueue calls. Fix issue with webrtc blocking on destruction. --- indra/llwebrtc/llwebrtc.cpp | 62 ++++--- indra/llwebrtc/llwebrtc.h | 3 - indra/llwebrtc/llwebrtc_impl.h | 16 +- indra/newview/llvoicewebrtc.cpp | 358 +++++++++++++++++----------------------- 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 connection; + mPeerConnection.swap(connection); + rtc::scoped_refptr dataChannel; + mDataChannel.swap(dataChannel); + rtc::scoped_refptr 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::CreateSessionDescription(webrtc::SdpType::kOffer, mangled_sdp)), + rtc::scoped_refptr(this)); - mPeerConnection->SetLocalDescription(std::unique_ptr(webrtc::CreateSessionDescription(webrtc::SdpType::kOffer, sdp_mangled_stream.str())), - rtc::scoped_refptr(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 mPeerConnectionFactory; - bool mMute; + bool mMute; // signaling - std::vector mSignalingObserverList; + std::vector mSignalingObserverList; std::vector> mCachedIceCandidates; - bool mAnswerReceived; + bool mAnswerReceived; - rtc::scoped_refptr mPeerConnection; - rtc::scoped_refptr mLocalStream; + rtc::scoped_refptr mPeerConnection; + rtc::scoped_refptr mLocalStream; // data - std::vector mDataObserverList; - rtc::scoped_refptr mDataChannel; + std::vector mDataObserverList; + rtc::scoped_refptr 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; }; -- cgit v1.2.3 From 0e2fc4d35ea1fdef0028a5132602985da2e1c463 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Tue, 19 Mar 2024 17:05:56 -0700 Subject: Clear out observers when terminating a connection --- autobuild.xml | 24 +++++++++++++++++++----- indra/llwebrtc/llwebrtc.cpp | 8 -------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3a3e2e5f14..f9c99514a1 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2901,15 +2901,29 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors creds github hash - 8b0191fae0860782a3e79b886364129c433cfd6b + a49fb3bb8aaf8325e7c6c4b6036db3da16afa2c9 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-webrtc-build/releases/assets/157215889 + https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.53/webrtc-m114.5735.08.53.8337236647-darwin64-8337236647.tar.zst name darwin64 + linux64 + + archive + + hash + 598baa054f63624a8e16883541c1f3dc7aa15a8a + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.53/webrtc-m114.5735.08.53.8337236647-linux64-8337236647.tar.zst + + name + linux64 + windows64 archive @@ -2917,11 +2931,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors creds github hash - 64eccac933cee532dc065d9f9729a21d8347aae4 + 59d5f2e40612ab7b0b1a5da8ba288f48d5979216 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-webrtc-build/releases/assets/157215892 + https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.53/webrtc-m114.5735.08.53.8337236647-windows64-8337236647.tar.zst name windows64 @@ -2934,7 +2948,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors vcs_url https://github.com/secondlife/3p-webrtc-build version - m114.5735.08.52.8319849783 + m114.5735.08.53.8337236647 xmlrpc-epi diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 283b94dd3c..34d950b804 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -1135,14 +1135,6 @@ 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; -- cgit v1.2.3