diff --git a/.hgtags b/.hgtags index c2f496d31b..0f28b62de7 100755 --- a/.hgtags +++ b/.hgtags @@ -578,3 +578,4 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release 2ea47f358b171178eb9a95503a1670d519c2886f 5.1.5-release 04538b8157c1f5cdacd9403f0a395452d4a93689 5.1.6-release ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release +23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index d4bda08b51..fc3aa7739a 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -5.1.8 +5.1.9 diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index a33b0a1e14..4e7c48bf65 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -84,7 +84,7 @@ LLVoiceHandler gVoiceHandler; std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus) { - std::string result = "UNKNOWN"; + std::string result = "UNTRANSLATED"; // Prevent copy-paste errors when updating this list... #define CASE(x) case x: result = #x; break @@ -97,12 +97,18 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv CASE(STATUS_JOINED); CASE(STATUS_LEFT_CHANNEL); CASE(STATUS_VOICE_DISABLED); + CASE(STATUS_VOICE_ENABLED); CASE(BEGIN_ERROR_STATUS); CASE(ERROR_CHANNEL_FULL); CASE(ERROR_CHANNEL_LOCKED); CASE(ERROR_NOT_AVAILABLE); CASE(ERROR_UNKNOWN); default: + { + std::ostringstream stream; + stream << "UNKNOWN(" << (int)inStatus << ")"; + result = stream.str(); + } break; } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index f53cb9be5c..01f7718df7 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -99,6 +99,7 @@ namespace { const int CONNECT_RETRY_MAX = 3; const F32 LOGIN_ATTEMPT_TIMEOUT = 30.0f; + const F32 LOGOUT_ATTEMPT_TIMEOUT = 5.0f; const int LOGIN_RETRY_MAX = 3; const F32 PROVISION_RETRY_TIMEOUT = 2.0; @@ -259,9 +260,16 @@ static void killGateway() { if (sGatewayPtr) { + LL_DEBUGS("Voice") << "SLVoice " << sGatewayPtr->getStatusString() << LL_ENDL; + sGatewayPump.stopListening("VivoxDaemonPump"); - sGatewayPtr->kill(); + sGatewayPtr->kill(__FUNCTION__); + sGatewayPtr=NULL; } + else + { + LL_DEBUGS("Voice") << "no gateway" << LL_ENDL; + } } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -424,6 +432,7 @@ void LLVivoxVoiceClient::cleanUp() deleteAllSessions(); deleteAllVoiceFonts(); deleteVoiceFontTemplates(); + LL_DEBUGS("Voice") << "exiting" << LL_ENDL; } //--------------------------------------------------- @@ -696,18 +705,18 @@ void LLVivoxVoiceClient::idle(void* user_data) // void LLVivoxVoiceClient::voiceControlCoro() { + LL_DEBUGS("Voice") << "starting" << LL_ENDL; mIsCoroutineActive = true; LLCoros::set_consuming(true); while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { - LL_INFOS("Voice") << "Suspending voiceControlCoro() due to teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL; + LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL; llcoro::suspendUntilTimeout(1.0); } do { - if (startAndConnectSession()) { if (mTuningMode) @@ -717,6 +726,7 @@ void LLVivoxVoiceClient::voiceControlCoro() waitForChannel(); // this doesn't normally return unless relog is needed or shutting down + LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL; endAndDisconnectSession(); } @@ -724,16 +734,23 @@ void LLVivoxVoiceClient::voiceControlCoro() // that we attempted to relog into Vivox and were rejected. // Rather than just quit out of voice, we will tear it down (above) // and then reconstruct the voice connecion from scratch. + LL_DEBUGS("Voice") + << "disconnected" + << " RelogRequested=" << mRelogRequested + << LL_ENDL; if (mRelogRequested) { + LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL; while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { + LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL; llcoro::suspendUntilTimeout(1.0); } } } - while (mRelogRequested); + while (mVoiceEnabled && mRelogRequested); mIsCoroutineActive = false; + LL_INFOS("Voice") << "exiting" << LL_ENDL; } @@ -765,6 +782,8 @@ bool LLVivoxVoiceClient::startAndConnectSession() bool LLVivoxVoiceClient::endAndDisconnectSession() { + LL_DEBUGS("Voice") << LL_ENDL; + breakVoiceConnection(true); killGateway(); @@ -774,15 +793,15 @@ bool LLVivoxVoiceClient::endAndDisconnectSession() bool LLVivoxVoiceClient::callbackEndDaemon(const LLSD& data) { - LL_DEBUGS("Voice") << LL_ENDL; - if (!LLAppViewer::isExiting()) + if (!LLAppViewer::isExiting() && mVoiceEnabled) { - LL_DEBUGS("Voice") << "SLVoice terminated " << ll_stream_notation_sd(data) << LL_ENDL; + LL_WARNS("Voice") << "SLVoice terminated " << ll_stream_notation_sd(data) << LL_ENDL; terminateAudioSession(false); closeSocket(); cleanUp(); LLVoiceClient::getInstance()->setUserPTTState(false); gAgent.setVoiceConnected(false); + mRelogRequested = true; } sGatewayPump.stopListening("VivoxDaemonPump"); return false; @@ -954,6 +973,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() mMainSessionGroupHandle.clear(); } + else + { + LL_DEBUGS("Voice") << " gateway running; not attempting to start" << LL_ENDL; + } //--------------------------------------------------------------------- llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); @@ -1168,7 +1191,7 @@ bool LLVivoxVoiceClient::establishVoiceConnection() bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait) { - LL_DEBUGS("Voice") << LL_ENDL; + LL_DEBUGS("Voice") << "( wait=" << corowait << ")" << LL_ENDL; LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); bool retval(true); @@ -1177,7 +1200,9 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait) if (corowait) { - LLSD result = llcoro::suspendUntilEventOn(voicePump); + LLSD timeoutResult(LLSDMap("connector", "timeout")); + + LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult); LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL; retval = result.has("connector"); @@ -1215,6 +1240,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait) #endif } + LL_DEBUGS("Voice") << "closing SLVoice socket" << LL_ENDL; closeSocket(); // Need to do this now -- bad things happen if the destructor does it later. cleanUp(); mConnected = false; @@ -1316,34 +1342,35 @@ bool LLVivoxVoiceClient::loginToVivox() void LLVivoxVoiceClient::logoutOfVivox(bool wait) { - - if (!mIsLoggedIn) - return; - - // Ensure that we'll re-request provisioning before logging in again - mAccountPassword.clear(); - mVoiceAccountServerURI.clear(); - - logoutSendMessage(); - - if (wait) + if (mIsLoggedIn) { - LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - // Typo fix - //LLSD timeoutResult(LLSDMap("lougout", "timeout")); - LLSD timeoutResult(LLSDMap("logout", "timeout")); - // + // Ensure that we'll re-request provisioning before logging in again + mAccountPassword.clear(); + mVoiceAccountServerURI.clear(); - LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult); + logoutSendMessage(); - LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL; - - if (result.has("logout")) + if (wait) { - } - } + LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); + LLSD timeoutResult(LLSDMap("logout", "timeout")); - mIsLoggedIn = false; + LL_DEBUGS("Voice") + << "waiting for logout response on " + << voicePump.getName() + << LL_ENDL; + + LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult); + + LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL; + } + else + { + LL_DEBUGS("Voice") << "not waiting for logout" << LL_ENDL; + } + + mIsLoggedIn = false; + } } @@ -1684,7 +1711,9 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait) LLSD result; do { - result = llcoro::suspendUntilEventOn(voicePump); + LLSD timeoutResult(LLSDMap("session", "timeout")); + + result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult); LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL; if (result.has("session")) @@ -1699,7 +1728,7 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait) } std::string message = result["session"].asString(); - if (message == "removed") + if (message == "removed" || message == "timeout") break; } } while (true); @@ -1726,7 +1755,6 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait) // The old session may now need to be deleted. reapSession(oldSession); - } else { @@ -1740,13 +1768,15 @@ bool LLVivoxVoiceClient::terminateAudioSession(bool wait) // the region chat. mSessionTerminateRequested = false; - if ((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting()) - { - // Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state). - return true; - } - - return false; + bool status=((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting()); + LL_DEBUGS("Voice") << "exiting" + << " VoiceEnabled " << mVoiceEnabled + << " IsInitialized " << mIsInitialized + << " RelogRequested " << mRelogRequested + << " AppExiting " << LLApp::isExiting() + << " returning " << status + << LL_ENDL; + return status; } bool LLVivoxVoiceClient::waitForChannel() @@ -1810,7 +1840,18 @@ bool LLVivoxVoiceClient::waitForChannel() sessionStatePtr_t joinSession = mNextAudioSession; mNextAudioSession.reset(); if (!runSession(joinSession)) + { + LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL; break; + } + else + { + LL_DEBUGS("Voice") + << "runSession returned true to inner loop" + << " RelogRequested=" << mRelogRequested + << " VoiceEnabled=" << mVoiceEnabled + << LL_ENDL; + } } if (!mNextAudioSession) @@ -1819,6 +1860,12 @@ bool LLVivoxVoiceClient::waitForChannel() } } while (mVoiceEnabled && !mRelogRequested); + LL_DEBUGS("Voice") + << "leaving inner waitForChannel loop" + << " RelogRequested=" << mRelogRequested + << " VoiceEnabled=" << mVoiceEnabled + << LL_ENDL; + mIsProcessingChannels = false; logoutOfVivox(true); @@ -1833,8 +1880,13 @@ bool LLVivoxVoiceClient::waitForChannel() return false; } } - } while (mVoiceEnabled && mRelogRequested); + } while (mVoiceEnabled && mRelogRequested && isGatewayRunning()); + LL_DEBUGS("Voice") + << "exiting" + << " RelogRequested=" << mRelogRequested + << " VoiceEnabled=" << mVoiceEnabled + << LL_ENDL; return true; } @@ -1867,7 +1919,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) mIsInChannel = true; mMuteMicDirty = true; - while (mVoiceEnabled && !mSessionTerminateRequested && !mTuningMode) + while (mVoiceEnabled && isGatewayRunning() && !mSessionTerminateRequested && !mTuningMode) { sendCaptureAndRenderDevices(); if (mAudioSession && mAudioSession->mParticipantsChanged) @@ -1917,7 +1969,9 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) mIsInitialized = true; LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, UPDATE_THROTTLE_SECONDS, timeoutEvent); if (!result.has("timeout")) // logging the timeout event spams the log + { LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL; + } if (result.has("session")) { if (result.has("handle")) @@ -1938,6 +1992,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) if (message == "removed") { + LL_DEBUGS("Voice") << "session removed" << LL_ENDL; notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL); break; } @@ -1947,12 +2002,12 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) std::string message = result["login"]; if (message == "account_logout") { + LL_DEBUGS("Voice") << "logged out" << LL_ENDL; mIsLoggedIn = false; mRelogRequested = true; break; } } - } mIsInChannel = false; @@ -3138,8 +3193,6 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates() { // Check all of the dirty states and then send messages to those needing to be changed. // Tuningmode hands its own mute settings. - LL_DEBUGS("Voice")<activate(); status = LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED; @@ -5203,6 +5263,10 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled) { LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro();", boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance())); + } + else + { + LL_DEBUGS("Voice") << "coro should be active.. not launching" << LL_ENDL; } } else @@ -5211,8 +5275,13 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled) LLVoiceChannel::getCurrentVoiceChannel()->deactivate(); status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED; } - notifyStatusObservers(status); + + notifyStatusObservers(status); } + else + { + LL_DEBUGS("Voice") << " no-op" << LL_ENDL; + } } // Bypass LLCachedControls for voice status update @@ -5930,7 +5999,7 @@ void LLVivoxVoiceClient::deleteSession(const sessionStatePtr_t &session) void LLVivoxVoiceClient::deleteAllSessions() { - LL_DEBUGS("Voice") << "called" << LL_ENDL; + LL_DEBUGS("Voice") << LL_ENDL; while (!mSessionsByHandle.empty()) { @@ -5981,6 +6050,10 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status) { + LL_DEBUGS("Voice") << "( " << LLVoiceClientStatusObserver::status2string(status) << " )" + << " mAudioSession=" << mAudioSession + << LL_ENDL; + if(mAudioSession) { if(status == LLVoiceClientStatusObserver::ERROR_UNKNOWN) @@ -6025,8 +6098,8 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta LL_DEBUGS("Voice") << " " << LLVoiceClientStatusObserver::status2string(status) << ", session URI " << getAudioSessionURI() - << (inSpatialChannel()?", proximal is true":", proximal is false") - << LL_ENDL; + << ", proximal is " << inSpatialChannel() + << LL_ENDL; for (status_observer_set_t::iterator it = mStatusObservers.begin(); it != mStatusObservers.end();