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 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.cpp | 38 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.h | 9 | ||||
| -rwxr-xr-x | indra/newview/llappcorehttp.cpp | 5 | ||||
| -rwxr-xr-x | indra/newview/llvoicevivox.cpp | 77 | 
8 files changed, 111 insertions, 64 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/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 9a23ede81b..7742cbc182 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -41,14 +41,41 @@  #include "message.h" // for getting the port -using namespace LLCore; +using namespace LLCore;  namespace LLCoreHttpUtil  {  const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; +namespace  +{ +    const std::string   HTTP_LOGBODY_KEY("HTTPLogBodyOnError"); + +    BoolSettingQuery_t  mBoolSettingGet; +    BoolSettingUpdate_t mBoolSettingPut; + +    inline bool getBoolSetting(const std::string &keyname) +    { +        if (!mBoolSettingGet || mBoolSettingGet.empty()) +            return(false); +        return mBoolSettingGet(HTTP_LOGBODY_KEY); +    } + +} + +void setPropertyMethods(BoolSettingQuery_t queryfn, BoolSettingUpdate_t updatefn) +{ +    mBoolSettingGet = queryfn; +    mBoolSettingPut = updatefn; + +    if (mBoolSettingPut && !mBoolSettingPut.empty()) +    { +        mBoolSettingPut(HTTP_LOGBODY_KEY, false, "Log the entire HTTP body in the case of an HTTP error."); +    } +} +  void logMessageSuccess(std::string logAuth, std::string url, std::string message)  { @@ -293,10 +320,11 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons          bas >> std::noskipws;          bodyData.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());          httpStatus["error_body"] = LLSD(bodyData); -#if 1 -        // commenting out, but keeping since this can be useful for debugging -        LL_WARNS() << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL; -#endif +        if (getBoolSetting(HTTP_LOGBODY_KEY)) +        { +            // commenting out, but keeping since this can be useful for debugging +            LL_WARNS() << "Returned body=" << std::endl << httpStatus["error_body"].asString() << LL_ENDL; +        }      }      mReplyPump.post(result); diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index d21f5ff45c..6f0b865f83 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -57,7 +57,14 @@  ///  namespace LLCoreHttpUtil  { -    extern const F32 HTTP_REQUEST_EXPIRY_SECS; +/// Allow access to to the property settings methods. +typedef boost::function<bool(const std::string &)> BoolSettingQuery_t; +typedef boost::function<void(const std::string &, bool, const std::string &)> BoolSettingUpdate_t; + +void setPropertyMethods(BoolSettingQuery_t queryfn, BoolSettingUpdate_t updatefn); + + +extern const F32 HTTP_REQUEST_EXPIRY_SECS;  /// Attempt to convert a response object's contents to LLSD.  /// It is expected that the response body will be of non-zero diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index 7dee309a62..49291ea564 100755 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -36,6 +36,8 @@  #include "llsecapi.h"  #include <curl/curl.h> +#include "llcorehttputil.h" +  // Here is where we begin to get our connection usage under control.  // This establishes llcorehttp policy classes that, among other  // things, limit the maximum number of connections to outside @@ -138,6 +140,9 @@ LLAppCoreHttp::~LLAppCoreHttp()  void LLAppCoreHttp::init()  { +    LLCoreHttpUtil::setPropertyMethods( +        boost::bind(&LLControlGroup::getBOOL, boost::ref(gSavedSettings), _1), +        boost::bind(&LLControlGroup::declareBOOL, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_NONDFT));      LLCore::LLHttp::initialize(); 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);  }  | 
