summaryrefslogtreecommitdiff
path: root/indra/llcommon/lleventcoro.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lleventcoro.cpp')
-rwxr-xr-xindra/llcommon/lleventcoro.cpp127
1 files changed, 17 insertions, 110 deletions
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index ad02e139b8..be93e9c83b 100755
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -41,23 +41,7 @@
#include "llerror.h"
#include "llcoros.h"
-namespace
-{
-
-/**
- * waitForEventOn() permits a coroutine to temporarily listen on an
- * LLEventPump any number of times. We don't really want to have to ask
- * the caller to label each such call with a distinct string; the whole
- * point of waitForEventOn() is to present a nice sequential interface to
- * the underlying LLEventPump-with-named-listeners machinery. So we'll use
- * LLEventPump::inventName() to generate a distinct name for each
- * temporary listener. On the other hand, because a given coroutine might
- * call waitForEventOn() any number of times, we don't really want to
- * consume an arbitrary number of generated inventName()s: that namespace,
- * though large, is nonetheless finite. So we memoize an invented name for
- * each distinct coroutine instance.
- */
-std::string listenerNameForCoro()
+std::string LLEventDetail::listenerNameForCoro()
{
// If this coroutine was launched by LLCoros::launch(), find that name.
std::string name(LLCoros::instance().getName());
@@ -72,25 +56,7 @@ std::string listenerNameForCoro()
return name;
}
-/**
- * Implement behavior described for postAndWait()'s @a replyPumpNamePath
- * parameter:
- *
- * * If <tt>path.isUndefined()</tt>, do nothing.
- * * If <tt>path.isString()</tt>, @a dest is an LLSD map: store @a value
- * into <tt>dest[path.asString()]</tt>.
- * * If <tt>path.isInteger()</tt>, @a dest is an LLSD array: store @a
- * value into <tt>dest[path.asInteger()]</tt>.
- * * If <tt>path.isArray()</tt>, iteratively apply the rules above to step
- * down through the structure of @a dest. The last array entry in @a
- * path specifies the entry in the lowest-level structure in @a dest
- * into which to store @a value.
- *
- * @note
- * In the degenerate case in which @a path is an empty array, @a dest will
- * @em become @a value rather than @em containing it.
- */
-void storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
+void LLEventDetail::storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
{
if (rawPath.isUndefined())
{
@@ -143,24 +109,14 @@ void storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
*pdest = value;
}
-} // anonymous
-
-void llcoro::yield()
-{
- // By viewer convention, we post an event on the "mainloop" LLEventPump
- // each iteration of the main event-handling loop. So waiting for a single
- // event on "mainloop" gives us a one-frame yield.
- waitForEventOn("mainloop");
-}
-
-LLSD llcoro::postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
- const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath)
+LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+ const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath)
{
// declare the future
- boost::dcoroutines::future<LLSD> future(llcoro::get_self());
+ boost::dcoroutines::future<LLSD> future(LLCoros::get_self());
// make a callback that will assign a value to the future, and listen on
// the specified LLEventPump with that callback
- std::string listenerName(listenerNameForCoro());
+ std::string listenerName(LLEventDetail::listenerNameForCoro());
LLTempBoundListener connection(
replyPump.getPump().listen(listenerName,
voidlistener(boost::dcoroutines::make_callback(future))));
@@ -170,7 +126,7 @@ LLSD llcoro::postAndWait(const LLSD& event, const LLEventPumpOrPumpName& request
// If replyPumpNamePath is non-empty, store the replyPump name in the
// request event.
LLSD modevent(event);
- storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
+ LLEventDetail::storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
<< " posting to " << requestPump.getPump().getName()
<< LL_ENDL;
@@ -186,7 +142,7 @@ LLSD llcoro::postAndWait(const LLSD& event, const LLEventPumpOrPumpName& request
LLSD value;
{
// instantiate Suspending to manage the "current" coroutine
- llcoro::Suspending suspended;
+ LLCoros::Suspending suspended;
value = *future;
} // destroy Suspending as soon as we're back
LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
@@ -195,53 +151,6 @@ LLSD llcoro::postAndWait(const LLSD& event, const LLEventPumpOrPumpName& request
return value;
}
-namespace
-{
-
-/**
- * This helper is specifically for the two-pump version of waitForEventOn().
- * We use a single future object, but we want to listen on two pumps with it.
- * Since we must still adapt from (the callable constructed by)
- * boost::dcoroutines::make_callback() (void return) to provide an event
- * listener (bool return), we've adapted VoidListener for the purpose. The
- * basic idea is that we construct a distinct instance of WaitForEventOnHelper
- * -- binding different instance data -- for each of the pumps. Then, when a
- * pump delivers an LLSD value to either WaitForEventOnHelper, it can combine
- * that LLSD with its discriminator to feed the future object.
- */
-template <typename LISTENER>
-class WaitForEventOnHelper
-{
-public:
- WaitForEventOnHelper(const LISTENER& listener, int discriminator):
- mListener(listener),
- mDiscrim(discriminator)
- {}
- // this signature is required for an LLEventPump listener
- bool operator()(const LLSD& event)
- {
- // our future object is defined to accept LLEventWithID
- mListener(LLEventWithID(event, mDiscrim));
- // don't swallow the event, let other listeners see it
- return false;
- }
-private:
- LISTENER mListener;
- const int mDiscrim;
-};
-
-/// WaitForEventOnHelper type-inference helper
-template <typename LISTENER>
-WaitForEventOnHelper<LISTENER> wfeoh(const LISTENER& listener, int discriminator)
-{
- return WaitForEventOnHelper<LISTENER>(listener, discriminator);
-}
-
-} // anonymous
-
-namespace llcoro
-{
-
LLEventWithID postAndWait2(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
const LLEventPumpOrPumpName& replyPump0,
@@ -250,26 +159,26 @@ LLEventWithID postAndWait2(const LLSD& event,
const LLSD& replyPump1NamePath)
{
// declare the future
- boost::dcoroutines::future<LLEventWithID> future(llcoro::get_self());
+ boost::dcoroutines::future<LLEventWithID> future(LLCoros::get_self());
// either callback will assign a value to this future; listen on
// each specified LLEventPump with a callback
- std::string name(listenerNameForCoro());
+ std::string name(LLEventDetail::listenerNameForCoro());
LLTempBoundListener connection0(
replyPump0.getPump().listen(name + "a",
- wfeoh(boost::dcoroutines::make_callback(future), 0)));
+ LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 0)));
LLTempBoundListener connection1(
replyPump1.getPump().listen(name + "b",
- wfeoh(boost::dcoroutines::make_callback(future), 1)));
+ LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 1)));
// skip the "post" part if requestPump is default-constructed
if (requestPump)
{
// If either replyPumpNamePath is non-empty, store the corresponding
// replyPump name in the request event.
LLSD modevent(event);
- storeToLLSDPath(modevent, replyPump0NamePath,
- replyPump0.getPump().getName());
- storeToLLSDPath(modevent, replyPump1NamePath,
- replyPump1.getPump().getName());
+ LLEventDetail::storeToLLSDPath(modevent, replyPump0NamePath,
+ replyPump0.getPump().getName());
+ LLEventDetail::storeToLLSDPath(modevent, replyPump1NamePath,
+ replyPump1.getPump().getName());
LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
<< " posting to " << requestPump.getPump().getName()
<< ": " << modevent << LL_ENDL;
@@ -282,7 +191,7 @@ LLEventWithID postAndWait2(const LLSD& event,
LLEventWithID value;
{
// instantiate Suspending to manage "current" coroutine
- llcoro::Suspending suspended;
+ LLCoros::Suspending suspended;
value = *future;
} // destroy Suspending as soon as we're back
LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << name
@@ -318,5 +227,3 @@ LLSD errorLog(const LLEventWithID& result, const std::string& desc)
// A simple return must therefore be from the reply pump (pump 0).
return result.first;
}
-
-} // namespace llcoro