summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-10-28 18:41:10 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2021-10-28 21:25:38 +0300
commit404e69e5945d357d70bd2da684b7a3dbedd1579d (patch)
tree8475939464b841964914ec14327db6fb54bb89a0
parent8acce67f95bab5bfae06a2f5d9de8bf9234c8b21 (diff)
SL-15462 Convert waitForChannel() into state machine
-rw-r--r--indra/newview/llappviewer.cpp6
-rw-r--r--indra/newview/llvoicevivox.cpp232
2 files changed, 171 insertions, 67 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3ec6d3f90e..f668dc754d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1520,6 +1520,12 @@ bool LLAppViewer::doFrame()
{
pauseMainloopTimeout();
saveFinalSnapshot();
+
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->terminate();
+ }
+
disconnectViewer();
resumeMainloopTimeout();
}
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 4aa6f2c6b2..c7a544f8eb 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -400,6 +400,11 @@ void LLVivoxVoiceClient::init(LLPumpIO *pump)
void LLVivoxVoiceClient::terminate()
{
+ if (sShuttingDown)
+ {
+ return;
+ }
+
// needs to be done manually here since we will not get another pass in
// coroutines... that mechanism is long since gone.
if (mIsLoggedIn)
@@ -1126,6 +1131,11 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
LLVoiceVivoxStats::getInstance()->provisionAttemptStart();
result = httpAdapter->postAndSuspend(httpRequest, url, LLSD(), httpOpts);
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -1133,14 +1143,12 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
{
F32 timeout = pow(PROVISION_RETRY_TIMEOUT, static_cast<float>(retryCount));
LL_WARNS("Voice") << "Provision CAP 404. Retrying in " << timeout << " seconds. Retries: " << (S32)retryCount << LL_ENDL;
+ llcoro::suspendUntilTimeout(timeout);
+
if (sShuttingDown)
{
return false;
}
- else
- {
- llcoro::suspendUntilTimeout(timeout);
- }
}
else if (!status)
{
@@ -1515,6 +1523,11 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, LLSD());
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -1620,6 +1633,11 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
llcoro::suspend();
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
LLSD result;
if (mSpatialJoiningNum == MAX_NORMAL_JOINING_SPATIAL_NUM)
@@ -1685,7 +1703,6 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
if (sShuttingDown)
{
- mIsJoiningSession = false;
return false;
}
@@ -1808,6 +1825,11 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
{
@@ -1870,54 +1892,76 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait)
return status;
}
+
+typedef enum e_voice_wait_for_channel_state
+{
+ VOICE_CHANNEL_STATE_LOGIN = 0, // entry point
+ VOICE_CHANNEL_STATE_CHECK_EFFECTS,
+ VOICE_CHANNEL_STATE_START_CHANNEL_PROCESSING,
+ VOICE_CHANNEL_STATE_PROCESS_CHANNEL,
+ VOICE_CHANNEL_STATE_NEXT_CHANNEL_DELAY,
+ VOICE_CHANNEL_STATE_NEXT_CHANNEL_CHECK,
+ VOICE_CHANNEL_STATE_LOGOUT,
+ VOICE_CHANNEL_STATE_RELOG,
+ VOICE_CHANNEL_STATE_DONE,
+} EVoiceWaitForChannelState;
+
bool LLVivoxVoiceClient::waitForChannel()
{
LL_INFOS("Voice") << "Waiting for channel" << LL_ENDL;
+ EVoiceWaitForChannelState state = VOICE_CHANNEL_STATE_LOGIN;
+
do
{
- if (!loginToVivox())
- {
- return false;
- }
-
if (sShuttingDown)
{
+ // terminate() forcefully disconects voice, no need for cleanup
return false;
}
- if (LLVoiceClient::instance().getVoiceEffectEnabled())
+ switch (state)
{
- retrieveVoiceFonts();
-
- if (sShuttingDown)
+ case VOICE_CHANNEL_STATE_LOGIN:
+ if (!loginToVivox())
{
return false;
}
+ state = VOICE_CHANNEL_STATE_CHECK_EFFECTS;
+ break;
- // Request the set of available voice fonts.
- refreshVoiceEffectLists(false);
- }
+ case VOICE_CHANNEL_STATE_CHECK_EFFECTS:
+ if (LLVoiceClient::instance().getVoiceEffectEnabled())
+ {
+ retrieveVoiceFonts();
-#if USE_SESSION_GROUPS
- // Rider: This code is completely unchanged from the original state machine
- // It does not seem to be in active use... but I'd rather not rip it out.
- // create the main session group
- setState(stateCreatingSessionGroup);
- sessionGroupCreateSendMessage();
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
+ // Request the set of available voice fonts.
+ refreshVoiceEffectLists(false);
+ }
+
+#if USE_SESSION_GROUPS
+ // Rider: This code is completely unchanged from the original state machine
+ // It does not seem to be in active use... but I'd rather not rip it out.
+ // create the main session group
+ setState(stateCreatingSessionGroup);
+ sessionGroupCreateSendMessage();
#endif
- do
- {
+ state = VOICE_CHANNEL_STATE_START_CHANNEL_PROCESSING;
+ break;
+
+ case VOICE_CHANNEL_STATE_START_CHANNEL_PROCESSING:
mIsProcessingChannels = true;
llcoro::suspend();
+ state = VOICE_CHANNEL_STATE_PROCESS_CHANNEL;
+ break;
- if (sShuttingDown)
- {
- mRelogRequested = false;
- break;
- }
-
+ case VOICE_CHANNEL_STATE_PROCESS_CHANNEL:
if (mTuningMode)
{
performMicTuning();
@@ -1958,63 +2002,91 @@ bool LLVivoxVoiceClient::waitForChannel()
}
}
- if (!mNextAudioSession && !sShuttingDown)
+ state = VOICE_CHANNEL_STATE_NEXT_CHANNEL_DELAY;
+ break;
+
+ case VOICE_CHANNEL_STATE_NEXT_CHANNEL_DELAY:
+ if (!mNextAudioSession)
{
llcoro::suspendUntilTimeout(1.0);
}
+ state = VOICE_CHANNEL_STATE_NEXT_CHANNEL_CHECK;
+ break;
- if (sShuttingDown)
+ case VOICE_CHANNEL_STATE_NEXT_CHANNEL_CHECK:
+ if (mVoiceEnabled && !mRelogRequested)
{
- mRelogRequested = false;
+ state = VOICE_CHANNEL_STATE_START_CHANNEL_PROCESSING;
+ break;
+ }
+ else
+ {
+ mIsProcessingChannels = false;
+ LL_DEBUGS("Voice")
+ << "leaving inner waitForChannel loop"
+ << " RelogRequested=" << mRelogRequested
+ << " VoiceEnabled=" << mVoiceEnabled
+ << LL_ENDL;
+ state = VOICE_CHANNEL_STATE_LOGOUT;
break;
}
- } while (!sShuttingDown && mVoiceEnabled && !mRelogRequested);
-
- if (!sShuttingDown)
- {
- LL_DEBUGS("Voice")
- << "leaving inner waitForChannel loop"
- << " RelogRequested=" << mRelogRequested
- << " VoiceEnabled=" << mVoiceEnabled
- << LL_ENDL;
- }
- else
- {
- // if sShuttingDown is set, we already logged out
- LL_DEBUGS("Voice") << "leaving inner waitForChannel loop." << LL_ENDL;
- return false;
- }
-
- mIsProcessingChannels = false;
-
- logoutOfVivox(!sShuttingDown /*bool wait*/);
+ case VOICE_CHANNEL_STATE_LOGOUT:
+ logoutOfVivox(true /*bool wait*/);
+ if (mRelogRequested)
+ {
+ state = VOICE_CHANNEL_STATE_RELOG;
+ }
+ else
+ {
+ state = VOICE_CHANNEL_STATE_DONE;
+ }
+ break;
- if (mRelogRequested && !sShuttingDown)
- {
+ case VOICE_CHANNEL_STATE_RELOG:
LL_DEBUGS("Voice") << "Relog Requested, restarting provisioning" << LL_ENDL;
if (!provisionVoiceAccount())
{
+ if (sShuttingDown)
+ {
+ return false;
+ }
LL_WARNS("Voice") << "provisioning voice failed; giving up" << LL_ENDL;
giveUp();
return false;
}
+ if (mVoiceEnabled && mRelogRequested && isGatewayRunning())
+ {
+ state = VOICE_CHANNEL_STATE_LOGIN;
+ }
+ else
+ {
+ state = VOICE_CHANNEL_STATE_DONE;
+ }
+ break;
+ case VOICE_CHANNEL_STATE_DONE:
+ LL_DEBUGS("Voice")
+ << "exiting"
+ << " RelogRequested=" << mRelogRequested
+ << " VoiceEnabled=" << mVoiceEnabled
+ << LL_ENDL;
+ return !sShuttingDown;
}
- } while (!sShuttingDown && mVoiceEnabled && mRelogRequested && isGatewayRunning());
-
- LL_DEBUGS("Voice")
- << "exiting"
- << " RelogRequested=" << mRelogRequested
- << " VoiceEnabled=" << mVoiceEnabled
- << LL_ENDL;
- return !sShuttingDown;
+ } while (true);
}
bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
{
LL_INFOS("Voice") << "running new voice session " << session->mHandle << LL_ENDL;
- if (!addAndJoinSession(session))
+ bool joined_session = addAndJoinSession(session);
+
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
+ if (!joined_session)
{
notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN);
@@ -2038,9 +2110,19 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
mIsInChannel = true;
mMuteMicDirty = true;
- while (mVoiceEnabled && isGatewayRunning() && !mSessionTerminateRequested && !mTuningMode)
+ while (!sShuttingDown
+ && mVoiceEnabled
+ && isGatewayRunning()
+ && !mSessionTerminateRequested
+ && !mTuningMode)
{
sendCaptureAndRenderDevices(); // suspends
+
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
if (mSessionTerminateRequested)
{
break;
@@ -2070,10 +2152,15 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
// cap for the parcel voice info. If we can't request it
// then we don't have the cap URL so we do nothing and will
// recheck next time around
- if (requestParcelVoiceInfo())
+ if (requestParcelVoiceInfo()) // suspends
{ // The parcel voice URI has changed.. break out and reconnect.
break;
}
+
+ if (sShuttingDown)
+ {
+ return false;
+ }
}
// Do the calculation that enforces the listener<->speaker tether (and also updates the real camera position)
enforceTether();
@@ -2092,6 +2179,12 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
mIsInitialized = true;
LLSD result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, UPDATE_THROTTLE_SECONDS, timeoutEvent);
+
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
if (!result.has("timeout")) // logging the timeout event spams the log
{
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
@@ -2134,6 +2227,11 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
}
}
+ if (sShuttingDown)
+ {
+ return false;
+ }
+
mIsInChannel = false;
LL_DEBUGS("Voice") << "terminating at end of runSession" << LL_ENDL;
terminateAudioSession(true);