summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-19 22:17:00 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-05-22 20:40:39 +0300
commit663bf4d3eba16e1d0a781ac5261541e7e2d6b4f2 (patch)
treeaf5baa1610854e884745bcd8b0aa6bd136ccb9ed /indra
parent0c5fd5e8110f55c713c5cbf721769fa485746f77 (diff)
#4823 WebRTC crashes
Diffstat (limited to 'indra')
-rw-r--r--indra/llwebrtc/llwebrtc.cpp87
-rw-r--r--indra/newview/llvoicewebrtc.cpp32
2 files changed, 74 insertions, 45 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index a286f75f42..f4ecce63a6 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -841,22 +841,23 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl)
void LLWebRTCPeerConnectionImpl::terminate()
{
mPendingJobs++;
+ webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> self(this);
mWebRTCImpl->PostSignalingTask(
- [this]()
+ [self]()
{
- if (mPeerConnection)
+ if (self->mPeerConnection)
{
- if (mDataChannel)
+ if (self->mDataChannel)
{
{
- mDataChannel->Close();
- mDataChannel = nullptr;
+ self->mDataChannel->Close();
+ self->mDataChannel = nullptr;
}
}
// to remove 'Secondlife is recording' icon from taskbar
// if user was speaking
- auto senders = mPeerConnection->GetSenders();
+ auto senders = self->mPeerConnection->GetSenders();
for (auto& sender : senders)
{
auto track = sender->track();
@@ -866,24 +867,24 @@ void LLWebRTCPeerConnectionImpl::terminate()
}
}
- mPeerConnection->Close();
- if (mLocalStream)
+ self->mPeerConnection->Close();
+ if (self->mLocalStream)
{
- auto tracks = mLocalStream->GetAudioTracks();
+ auto tracks = self->mLocalStream->GetAudioTracks();
for (auto& track : tracks)
{
- mLocalStream->RemoveTrack(track);
+ self->mLocalStream->RemoveTrack(track);
}
- mLocalStream = nullptr;
+ self->mLocalStream = nullptr;
}
- mPeerConnection = nullptr;
+ self->mPeerConnection = nullptr;
- for (auto &observer : mSignalingObserverList)
+ for (auto &observer : self->mSignalingObserverList)
{
observer->OnPeerConnectionClosed();
}
}
- mPendingJobs--;
+ self->mPendingJobs--;
});
}
@@ -906,8 +907,9 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
mAnswerReceived = false;
mPendingJobs++;
+ webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> self(this);
mWebRTCImpl->PostSignalingTask(
- [this,options]()
+ [self,options]()
{
webrtc::PeerConnectionInterface::RTCConfiguration config;
for (auto server : options.mServers)
@@ -926,42 +928,42 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
config.set_min_port(60000);
config.set_max_port(60100);
- webrtc::PeerConnectionDependencies pc_dependencies(this);
+ webrtc::PeerConnectionDependencies pc_dependencies(self.get());
// Other thread manages mPeerConnectionFactory's lifetime and it can be reset
// at any momment, create own scoped_refptr (atomic).
- webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory = mPeerConnectionFactory;
+ webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory = self->mPeerConnectionFactory;
if (peer_connection_factory == nullptr)
{
RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection, factory doesn't exist";
// Too early?
- mPendingJobs--;
+ self->mPendingJobs--;
return;
}
auto error_or_peer_connection = peer_connection_factory->CreatePeerConnectionOrError(config, std::move(pc_dependencies));
if (error_or_peer_connection.ok())
{
- mPeerConnection = std::move(error_or_peer_connection.value());
+ self->mPeerConnection = std::move(error_or_peer_connection.value());
}
else
{
RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection: " << error_or_peer_connection.error().message();
- for (auto &observer : mSignalingObserverList)
+ for (auto &observer : self->mSignalingObserverList)
{
observer->OnRenegotiationNeeded();
}
- mPendingJobs--;
+ self->mPendingJobs--;
return;
}
webrtc::DataChannelInit init;
init.ordered = true;
- auto data_channel_or_error = mPeerConnection->CreateDataChannelOrError("SLData", &init);
+ auto data_channel_or_error = self->mPeerConnection->CreateDataChannelOrError("SLData", &init);
if (data_channel_or_error.ok())
{
- mDataChannel = std::move(data_channel_or_error.value());
+ self->mDataChannel = std::move(data_channel_or_error.value());
- mDataChannel->RegisterObserver(this);
+ self->mDataChannel->RegisterObserver(self.get());
}
webrtc::AudioOptions audioOptions;
@@ -970,16 +972,16 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
audioOptions.noise_suppression = true;
audioOptions.init_recording_on_send = false;
- mLocalStream = peer_connection_factory->CreateLocalMediaStream("SLStream");
+ self->mLocalStream = peer_connection_factory->CreateLocalMediaStream("SLStream");
webrtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
peer_connection_factory->CreateAudioTrack("SLAudio", peer_connection_factory->CreateAudioSource(audioOptions).get()));
audio_track->set_enabled(false);
- mLocalStream->AddTrack(audio_track);
+ self->mLocalStream->AddTrack(audio_track);
- mPeerConnection->AddTrack(audio_track, {"SLStream"});
+ self->mPeerConnection->AddTrack(audio_track, {"SLStream"});
- auto senders = mPeerConnection->GetSenders();
+ auto senders = self->mPeerConnection->GetSenders();
for (auto &sender : senders)
{
@@ -995,7 +997,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
sender->SetParameters(params);
}
- auto receivers = mPeerConnection->GetReceivers();
+ auto receivers = self->mPeerConnection->GetReceivers();
for (auto &receiver : receivers)
{
webrtc::RtpParameters params;
@@ -1011,9 +1013,9 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
}
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions offerOptions;
- this->AddRef(); // CreateOffer will deref this when it's done. Without this, the callbacks never get called.
- mPeerConnection->CreateOffer(this, offerOptions);
- mPendingJobs--;
+ self->AddRef(); // CreateOffer will deref this when it's done. Without this, the callbacks never get called.
+ self->mPeerConnection->CreateOffer(self.get(), offerOptions);
+ self->mPendingJobs--;
});
return true;
@@ -1090,14 +1092,15 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
mPendingJobs++;
+ webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> self(this);
mWebRTCImpl->PostSignalingTask(
- [this, force_reset, enable]()
+ [self, force_reset, enable]()
{
- if (mPeerConnection)
+ if (self->mPeerConnection)
{
- auto senders = mPeerConnection->GetSenders();
+ auto senders = self->mPeerConnection->GetSenders();
- RTC_LOG(LS_INFO) << __FUNCTION__ << (mMute ? "disabling" : "enabling") << " streams count " << senders.size();
+ RTC_LOG(LS_INFO) << __FUNCTION__ << (self->mMute ? "disabling" : "enabling") << " streams count " << senders.size();
for (auto &sender : senders)
{
auto track = sender->track();
@@ -1113,7 +1116,7 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
track->set_enabled(enable);
}
}
- mPendingJobs--;
+ self->mPendingJobs--;
}
});
}
@@ -1253,12 +1256,14 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf
case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
{
mPendingJobs++;
- mWebRTCImpl->PostWorkerTask([this]() {
- for (auto &observer : mSignalingObserverList)
+ webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl> self(this);
+ mWebRTCImpl->PostWorkerTask([self]()
+ {
+ for (auto &observer : self->mSignalingObserverList)
{
- observer->OnAudioEstablished(this);
+ observer->OnAudioEstablished(self.get());
}
- mPendingJobs--;
+ self->mPendingJobs--;
});
break;
}
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 0125ea4e47..ecf963039f 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -1678,6 +1678,10 @@ void LLWebRTCVoiceClient::setVoiceVolume(F32 volume)
void LLWebRTCVoiceClient::predSetSpeakerVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 volume)
{
+ if (session->mShuttingDown)
+ {
+ return;
+ }
session->setSpeakerVolume(volume);
}
@@ -1906,6 +1910,10 @@ LLWebRTCVoiceClient::sessionState::sessionState() :
void LLWebRTCVoiceClient::predUpdateOwnVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 audio_level)
{
+ if (session->mShuttingDown)
+ {
+ return;
+ }
participantStatePtr_t participant = session->findParticipantByID(gAgentID);
if (participant)
{
@@ -1934,9 +1942,16 @@ void LLWebRTCVoiceClient::sessionState::sendData(const std::string &data)
void LLWebRTCVoiceClient::sessionState::setMuteMic(bool muted)
{
mMuted = muted;
+ if (mShuttingDown)
+ {
+ return;
+ }
for (auto &connection : mWebRTCConnections)
{
- connection->setMuteMic(muted);
+ if (!connection->isShuttingDown())
+ {
+ connection->setMuteMic(muted);
+ }
}
}
@@ -1945,7 +1960,10 @@ void LLWebRTCVoiceClient::sessionState::setSpeakerVolume(F32 volume)
mSpeakerVolume = volume;
for (auto &connection : mWebRTCConnections)
{
- connection->setSpeakerVolume(volume);
+ if (!connection->isShuttingDown())
+ {
+ connection->setSpeakerVolume(volume);
+ }
}
}
@@ -1957,7 +1975,10 @@ void LLWebRTCVoiceClient::sessionState::setUserVolume(const LLUUID &id, F32 volu
}
for (auto &connection : mWebRTCConnections)
{
- connection->setUserVolume(id, volume);
+ if (!connection->isShuttingDown())
+ {
+ connection->setUserVolume(id, volume);
+ }
}
}
@@ -1969,7 +1990,10 @@ void LLWebRTCVoiceClient::sessionState::setUserMute(const LLUUID &id, bool mute)
}
for (auto &connection : mWebRTCConnections)
{
- connection->setUserMute(id, mute);
+ if (!connection->isShuttingDown())
+ {
+ connection->setUserMute(id, mute);
+ }
}
}
/*static*/