diff options
Diffstat (limited to 'indra/llcommon')
| -rwxr-xr-x | indra/llcommon/lleventcoro.cpp | 22 | ||||
| -rwxr-xr-x | indra/llcommon/lleventcoro.h | 5 | ||||
| -rwxr-xr-x | indra/llcommon/lleventfilter.cpp | 4 | ||||
| -rwxr-xr-x | indra/llcommon/lleventfilter.h | 19 | ||||
| -rwxr-xr-x | indra/llcommon/llevents.h | 6 | 
5 files changed, 52 insertions, 4 deletions
| diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 578a2b62c8..2d5f964deb 100755 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -229,6 +229,28 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ      return value;  } +LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName,  +        F32 timeoutin, const LLSD &timeoutResult) +{ +    /** +     * 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(suspendPump); +} +  namespace  { diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 2105faf861..87926c692d 100755 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -147,6 +147,11 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump)      return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump);  } +/// 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  /// return type for two-pump variant of suspendUntilEventOn() diff --git a/indra/llcommon/lleventfilter.cpp b/indra/llcommon/lleventfilter.cpp index d36a107254..64ab58adcd 100755 --- a/indra/llcommon/lleventfilter.cpp +++ b/indra/llcommon/lleventfilter.cpp @@ -39,9 +39,9 @@  #include "llsdutil.h"               // llsd_matches()  LLEventFilter::LLEventFilter(LLEventPump& source, const std::string& name, bool tweak): -    LLEventStream(name, tweak) +    LLEventStream(name, tweak), +    mSource(source.listen(getName(), boost::bind(&LLEventFilter::post, this, _1)))  { -    source.listen(getName(), boost::bind(&LLEventFilter::post, this, _1));  }  LLEventMatching::LLEventMatching(const LLSD& pattern): diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index e822a664f5..66f3c14869 100755 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -49,6 +49,9 @@ public:      /// Post an event to all listeners      virtual bool post(const LLSD& event) = 0; + +private: +    LLTempBoundListener mSource;  };  /** @@ -181,11 +184,23 @@ protected:  private:      bool tick(const LLSD&); -    LLBoundListener mMainloop; +    LLTempBoundListener mMainloop;      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  { | 
