diff options
-rwxr-xr-x | indra/llcommon/lleventcoro.cpp | 21 | ||||
-rwxr-xr-x | indra/llcommon/lleventcoro.h | 5 | ||||
-rwxr-xr-x | indra/llcommon/lleventfilter.h | 14 | ||||
-rwxr-xr-x | indra/llcommon/llevents.h | 6 | ||||
-rwxr-xr-x | indra/newview/llvoicevivox.cpp | 77 |
5 files changed, 65 insertions, 58 deletions
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 44291eb711..2d5f964deb 100755 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -229,13 +229,26 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ return value; } -LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult) +LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, + F32 timeoutin, const LLSD &timeoutResult) { - LLEventTimeout timeoutPump(pump); + /** + * The timeout pump is attached upstream of of the waiting pump and will + * pass the timeout event through it. We CAN NOT attach downstream since + * doing so will cause the suspendPump to fire any waiting events immediately + * and they will be lost. This becomes especially problematic with the + * LLEventTimeout(pump) constructor which will also attempt to fire those + * events using the virtual listen_impl method in the not yet fully constructed + * timeoutPump. + */ + LLEventTimeout timeoutPump; + LLEventPump &suspendPump = suspendPumpOrName.getPump(); + + LLTempBoundListener timeoutListener(timeoutPump.listen(suspendPump.getName(), + boost::bind(&LLEventPump::post, &suspendPump, _1))); timeoutPump.eventAfter(timeoutin, timeoutResult); - return llcoro::suspendUntilEventOn(timeoutPump); - + return llcoro::suspendUntilEventOn(suspendPump); } namespace diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 19c68e1f35..87926c692d 100755 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -147,7 +147,10 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump) return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump); } -LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& pump, F32 timeoutin, const LLSD &timeoutResult); +/// Suspend the coroutine until an event is fired on the identified pump +/// or the timeout duration has elapsed. If the timeout duration +/// elapses the specified LLSD is returned. +LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, F32 timeoutin, const LLSD &timeoutResult); } // namespace llcoro diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 15bac5fd73..66f3c14869 100755 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -188,7 +188,19 @@ private: Action mAction; }; -/// Production implementation of LLEventTimoutBase +/** + * Production implementation of LLEventTimoutBase. + * + * @NOTE: Caution should be taken when using the LLEventTimeout(LLEventPump &) + * constructor to ensure that the upstream event pump is not an LLEventMaildrop + * or any other kind of store and forward pump which may have events outstanding. + * Using this constructor will cause the upstream event pump to fire any pending + * events and could result in the invocation of a virtual method before the timeout + * has been fully constructed. The timeout should instead be connected upstream + * from the event pump and attached using the listen method. + * See llcoro::suspendUntilEventOnWithTimeout() for an example. + */ + class LL_COMMON_API LLEventTimeout: public LLEventTimeoutBase { public: diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index 6175329a9d..ba4fcd766e 100755 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -616,6 +616,12 @@ public: * a queue. Subsequent attaching listeners will receive stored events from the queue * until a listener indicates that the event has been handled. In order to receive * multiple events from a mail drop the listener must disconnect and reconnect. + * + * @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or + * LLEventFilter attaching the filter downstream using Timeout's constructor will + * cause the MailDrop to discharge any of it's stored events. The timeout should + * instead be connected upstream using its listen() method. + * See llcoro::suspendUntilEventOnWithTimeout() for an example. */ class LL_COMMON_API LLEventMailDrop : public LLEventStream { diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 4316db115e..07427e0377 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -900,8 +900,7 @@ bool LLVivoxVoiceClient::loginToVivox() { LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - LLSD timeoutResult; - timeoutResult["login"] = LLSD::String("timeout"); + LLSD timeoutResult(LLSDMap("login", "timeout")); int loginRetryCount(0); @@ -1012,8 +1011,7 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait) if (wait) { LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); - LLSD timeoutResult; - timeoutResult["logout"] = LLSD::String("timeout"); + LLSD timeoutResult(LLSDMap("lougout", "timeout")); LLSD result = llcoro::suspendUntilEventOnWithTimeout(voicePump, LOGIN_ATTEMPT_TIMEOUT, timeoutResult); @@ -1216,8 +1214,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) bool added(true); bool joined(false); - LLSD timeoutResult; - timeoutResult["session"] = LLSD::String("timeout"); + LLSD timeoutResult(LLSDMap("session", "timeout")); // It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4 // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck. @@ -1498,8 +1495,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) notifyParticipantObservers(); notifyVoiceFontObservers(); - LLSD timeoutEvent = LLSD::emptyMap(); - timeoutEvent["timeout"] = LLSD::Boolean(true); + LLSD timeoutEvent(LLSDMap("timeout", LLSD::Boolean(true))); LLEventPump &voicePump = LLEventPumps::instance().obtain("vivoxClientPump"); mIsInChannel = true; @@ -1651,8 +1647,7 @@ void LLVivoxVoiceClient::recordingAndPlaybackMode() int LLVivoxVoiceClient::voiceRecordBuffer() { - LLSD timeoutResult; - timeoutResult["recplay"] = LLSD::String("stop"); + LLSD timeoutResult(LLSDMap("recplay", "stop")); LL_INFOS("Voice") << "Recording voice buffer" << LL_ENDL; @@ -1682,8 +1677,7 @@ int LLVivoxVoiceClient::voiceRecordBuffer() int LLVivoxVoiceClient::voicePlaybackBuffer() { - LLSD timeoutResult; - timeoutResult["recplay"] = LLSD::String("stop"); + LLSD timeoutResult(LLSDMap("recplay", "stop")); LL_INFOS("Voice") << "Playing voice buffer" << LL_ENDL; @@ -2922,11 +2916,9 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu session->mErrorStatusString = statusString; if(session == mAudioSession) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("failed"); - vivoxevent["reason"] = LLSD::Integer(statusCode); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "failed") + ("reason", LLSD::Integer(statusCode))); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -2943,10 +2935,8 @@ void LLVivoxVoiceClient::sessionCreateResponse(std::string &requestId, int statu { setSessionHandle(session, sessionHandle); } - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("created"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "created")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -2970,10 +2960,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId, session->mErrorStatusString = statusString; if(session == mAudioSession) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("failed"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "failed")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -2991,10 +2979,8 @@ void LLVivoxVoiceClient::sessionGroupAddSessionResponse(std::string &requestId, setSessionHandle(session, sessionHandle); } - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(sessionHandle); - vivoxevent["session"] = LLSD::String("added"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(sessionHandle)) + ("session", "added")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); @@ -3039,9 +3025,7 @@ void LLVivoxVoiceClient::logoutResponse(int statusCode, std::string &statusStrin LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL; // Should this ever fail? do we care if it does? } - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["logout"] = LLSD::Boolean(true); + LLSD vivoxevent(LLSDMap("logout", LLSD::Boolean(true))); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -3056,9 +3040,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string & mConnected = false; - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["connector"] = LLSD::Boolean(false); + LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false))); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -3166,10 +3148,8 @@ void LLVivoxVoiceClient::joinedAudioSession(const sessionStatePtr_t &session) // This is the session we're joining. if(mIsJoiningSession) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(session->mHandle); - vivoxevent["session"] = LLSD::String("joined"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle)) + ("session", "joined")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); @@ -3312,10 +3292,8 @@ void LLVivoxVoiceClient::leftAudioSession(const sessionStatePtr_t &session) { if (mAudioSession == session) { - LLSD vivoxevent = LLSD::emptyMap(); - - vivoxevent["handle"] = LLSD::String(session->mHandle); - vivoxevent["session"] = LLSD::String("removed"); + LLSD vivoxevent(LLSDMap("handle", LLSD::String(session->mHandle)) + ("session", "removed")); LLEventPumps::instance().post("vivoxClientPump", vivoxevent); } @@ -6170,9 +6148,7 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st { // *TODO: We seem to get multiple events of this type. Should figure a way to advance only after // receiving the last one. - LLSD result = LLSD::emptyMap(); - - result["voice_fonts"] = LLSD::Boolean(true); + LLSD result(LLSDMap("voice_fonts", LLSD::Boolean(true))); LLEventPumps::instance().post("vivoxClientPump", result); } @@ -6345,8 +6321,7 @@ void LLVivoxVoiceClient::recordPreviewBuffer() mCaptureBufferRecording = true; - LLSD result; - result["recplay"] = "record"; + LLSD result(LLSDMap("recplay", "record")); LLEventPumps::instance().post("vivoxClientPump", result); } @@ -6369,8 +6344,7 @@ void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id) mPreviewVoiceFont = effect_id; mCaptureBufferPlaying = true; - LLSD result; - result["recplay"] = "playback"; + LLSD result(LLSDMap("recplay", "playback")); LLEventPumps::instance().post("vivoxClientPump", result); } @@ -6379,8 +6353,7 @@ void LLVivoxVoiceClient::stopPreviewBuffer() mCaptureBufferRecording = false; mCaptureBufferPlaying = false; - LLSD result; - result["recplay"] = "quit"; + LLSD result(LLSDMap("recplay", "quit")); LLEventPumps::instance().post("vivoxClientPump", result); } |