summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2016-05-06 10:28:42 -0400
committerOz Linden <oz@lindenlab.com>2016-05-06 10:28:42 -0400
commit950c41d184b340a7a3370c2cbda5d1eed9a17b0b (patch)
tree373912394af6834d7d56258becf46954244b8423 /indra/llcommon
parent20198b750d02c769ab6845226f98ce6e5dd1f20b (diff)
parent7f5e6cea124e1193b199a3eabd50bdab96340c13 (diff)
merge 4.0.4-release and MAINT-5974
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/lleventcoro.cpp22
-rw-r--r--indra/llcommon/lleventcoro.h5
-rw-r--r--indra/llcommon/lleventfilter.cpp4
-rw-r--r--indra/llcommon/lleventfilter.h19
-rw-r--r--indra/llcommon/llevents.h6
5 files changed, 52 insertions, 4 deletions
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 578a2b62c8..2d5f964deb 100644
--- 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 100644
--- 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 100644
--- 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 100644
--- 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 100644
--- 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
{