summaryrefslogtreecommitdiff
path: root/indra/newview/llvoicewebrtc.cpp
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-08-06 21:13:33 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2024-08-07 07:48:19 +0300
commitb5c9a30e3da8d75b3343a79ba64b7cc81da9991e (patch)
tree1ef77c07f6e1739bfe48d06cc838f250153b4027 /indra/newview/llvoicewebrtc.cpp
parentbf21677305f7dc725cb0872ee3bcf251efef40f7 (diff)
viewer#2203 Crash at breakVoiceConnectionCoro
bar webrtc's coroutines from necromancy
Diffstat (limited to 'indra/newview/llvoicewebrtc.cpp')
-rw-r--r--indra/newview/llvoicewebrtc.cpp69
1 files changed, 35 insertions, 34 deletions
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 3164886494..f5105f0ca1 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -459,6 +459,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
// Could help with voice updates making for smoother
// voice when we're busy.
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
+ if (sShuttingDown) return; // 'this' migh already be invalid
bool voiceEnabled = mVoiceEnabled;
if (!isAgentAvatarValid())
@@ -2186,47 +2187,47 @@ void LLVoiceWebRTCConnection::processIceUpdates()
{
mOutstandingRequests++;
LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::processIceUpdatesCoro",
- boost::bind(&LLVoiceWebRTCConnection::processIceUpdatesCoro, this));
+ boost::bind(&LLVoiceWebRTCConnection::processIceUpdatesCoro, this->shared_from_this()));
}
// Ice candidates may be streamed in before or after the SDP offer is available (see below)
// This function determines whether candidates are available to send to the Secondlife WebRTC
// server via the simulator. If so, and there are no more candidates, this code
// will make the cap call to the server sending up the ICE candidates.
-void LLVoiceWebRTCConnection::processIceUpdatesCoro()
+void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
- if (mShutDown || LLWebRTCVoiceClient::isShuttingDown())
+ if (connection->mShutDown || LLWebRTCVoiceClient::isShuttingDown())
{
- mOutstandingRequests--;
+ connection->mOutstandingRequests--;
return;
}
bool iceCompleted = false;
LLSD body;
- if (!mIceCandidates.empty() || mIceCompleted)
+ if (!connection->mIceCandidates.empty() || connection->mIceCompleted)
{
- LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
+ LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(connection->mRegionID);
if (!regionp || !regionp->capabilitiesReceived())
{
LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL;
- mOutstandingRequests--;
+ connection->mOutstandingRequests--;
return;
}
std::string url = regionp->getCapability("VoiceSignalingRequest");
if (url.empty())
{
- mOutstandingRequests--;
+ connection->mOutstandingRequests--;
return;
}
LL_DEBUGS("Voice") << "region ready to complete voice signaling; url=" << url << LL_ENDL;
- if (!mIceCandidates.empty())
+ if (!connection->mIceCandidates.empty())
{
LLSD candidates = LLSD::emptyArray();
- for (auto &ice_candidate : mIceCandidates)
+ for (auto &ice_candidate : connection->mIceCandidates)
{
LLSD body_candidate;
body_candidate["sdpMid"] = ice_candidate.mSdpMid;
@@ -2235,18 +2236,18 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro()
candidates.append(body_candidate);
}
body["candidates"] = candidates;
- mIceCandidates.clear();
+ connection->mIceCandidates.clear();
}
- else if (mIceCompleted)
+ else if (connection->mIceCompleted)
{
LLSD body_candidate;
body_candidate["completed"] = true;
body["candidate"] = body_candidate;
- iceCompleted = mIceCompleted;
- mIceCompleted = false;
+ iceCompleted = connection->mIceCompleted;
+ connection->mIceCompleted = false;
}
- body["viewer_session"] = mViewerSession;
+ body["viewer_session"] = connection->mViewerSession;
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
@@ -2261,7 +2262,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro()
if (LLWebRTCVoiceClient::isShuttingDown())
{
- mOutstandingRequests--;
+ connection->mOutstandingRequests--;
return;
}
@@ -2271,10 +2272,10 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro()
if (!status)
{
// couldn't trickle the candidates, so restart the session.
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
}
}
- mOutstandingRequests--;
+ connection->mOutstandingRequests--;
}
@@ -2428,31 +2429,31 @@ 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.
-void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
+void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connection)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL;
- if (mWebRTCDataInterface)
+ if (connection->mWebRTCDataInterface)
{
- mWebRTCDataInterface->unsetDataObserver(this);
- mWebRTCDataInterface = nullptr;
+ connection->mWebRTCDataInterface->unsetDataObserver(connection.get());
+ connection->mWebRTCDataInterface = nullptr;
}
- mWebRTCAudioInterface = nullptr;
- LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID);
+ connection->mWebRTCAudioInterface = nullptr;
+ LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(connection->mRegionID);
if (!regionp || !regionp->capabilitiesReceived())
{
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
- mOutstandingRequests--;
+ connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ connection->mOutstandingRequests--;
return;
}
std::string url = regionp->getCapability("ProvisionVoiceAccountRequest");
if (url.empty())
{
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
- mOutstandingRequests--;
+ connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ connection->mOutstandingRequests--;
return;
}
@@ -2461,7 +2462,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
LLVoiceWebRTCStats::getInstance()->provisionAttemptStart();
LLSD body;
body["logout"] = TRUE;
- body["viewer_session"] = mViewerSession;
+ body["viewer_session"] = connection->mViewerSession;
body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE;
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
@@ -2472,15 +2473,15 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
httpOpts->setWantHeaders(true);
- mOutstandingRequests++;
+ connection->mOutstandingRequests++;
// 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);
- mOutstandingRequests--;
- setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
+ connection->mOutstandingRequests--;
+ connection->setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
}
// Tell the simulator to tell the Secondlife WebRTC server that we want a voice
@@ -2664,7 +2665,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
// VOICE_STATE_SESSION_ESTABLISHED via a callback on a webrtc thread.
setVoiceConnectionState(VOICE_STATE_CONNECTION_WAIT);
LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::requestVoiceConnectionCoro",
- boost::bind(&LLVoiceWebRTCConnection::requestVoiceConnectionCoro, this));
+ boost::bind(&LLVoiceWebRTCConnection::requestVoiceConnectionCoro, this->shared_from_this()));
break;
case VOICE_STATE_CONNECTION_WAIT:
@@ -2744,7 +2745,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
case VOICE_STATE_DISCONNECT:
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT);
LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro",
- boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this));
+ boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this->shared_from_this()));
break;
case VOICE_STATE_WAIT_FOR_EXIT: