summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rwxr-xr-xindra/llcommon/llcoros.cpp4
-rwxr-xr-xindra/llcommon/llcoros.h12
-rwxr-xr-xindra/llcommon/lleventcoro.cpp129
-rwxr-xr-xindra/llcommon/lleventcoro.h18
-rwxr-xr-xindra/llcommon/tests/lleventcoro_test.cpp3
5 files changed, 98 insertions, 68 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index d76401d01b..6cca5e7c60 100755
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -61,7 +61,7 @@ LLCoros::coro::self& LLCoros::get_self()
return *current->mSelf;
}
-llcoro::Suspending::Suspending():
+LLCoros::Suspending::Suspending():
mSuspended(LLCoros::sCurrentCoro.get())
{
// Revert mCurrentCoro to the value it had at the moment we last switched
@@ -69,7 +69,7 @@ llcoro::Suspending::Suspending():
LLCoros::sCurrentCoro.reset(mSuspended->mPrev);
}
-llcoro::Suspending::~Suspending()
+LLCoros::Suspending::~Suspending()
{
// Okay, we're back, update our mPrev
mSuspended->mPrev = LLCoros::sCurrentCoro.get();
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 56eed8cafe..05bd87dc3c 100755
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -144,6 +144,18 @@ public:
*/
std::string getName() const;
+ /// get the current coro::self& for those who really really care
+ static coro::self& get_self();
+
+ /// Instantiate one of these in a block surrounding any leaf point when
+ /// control literally switches away from this coroutine.
+ class Suspending
+ public:
+ Suspending();
+ ~Suspending();
+ private:
+ coro::self* mSuspended;
+ };
/// for delayed initialization
void setStackSize(S32 stacksize);
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 85af0d9b9f..a37b87f085 100755
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -41,7 +41,7 @@
#include "llerror.h"
#include "llcoros.h"
-namespace
+std::string LLEventDetail::listenerNameForCoro()
{
/**
@@ -143,24 +143,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(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 +160,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 +176,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,6 +185,72 @@ LLSD llcoro::postAndWait(const LLSD& event, const LLEventPumpOrPumpName& request
return value;
}
+LLEventWithID postAndWait2(const LLSD& event,
+ const LLEventPumpOrPumpName& requestPump,
+ const LLEventPumpOrPumpName& replyPump0,
+ const LLEventPumpOrPumpName& replyPump1,
+ const LLSD& replyPump0NamePath,
+ const LLSD& replyPump1NamePath)
+{
+ // declare the future
+ 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(LLEventDetail::listenerNameForCoro());
+ LLTempBoundListener connection0(
+ replyPump0.getPump().listen(name + "a",
+ LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 0)));
+ LLTempBoundListener connection1(
+ replyPump1.getPump().listen(name + "b",
+ 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);
+ 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;
+ requestPump.getPump().post(modevent);
+ }
+ LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
+ << " about to wait on LLEventPumps " << replyPump0.getPump().getName()
+ << ", " << replyPump1.getPump().getName() << LL_ENDL;
+ // trying to dereference ("resolve") the future makes us wait for it
+ LLEventWithID value;
+ {
+ // instantiate Suspending to manage "current" coroutine
+ LLCoros::Suspending suspended;
+ value = *future;
+ } // destroy Suspending as soon as we're back
+ LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << name
+ << " resuming with (" << value.first << ", " << value.second << ")"
+ << LL_ENDL;
+ // returning should disconnect both connections
+ return 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)
+ boost::dcoroutines::future<LLSD> future(llcoro::get_self());
+ std::string listenerName(listenerNameForCoro());
+ storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
+ llcoro::Suspending suspended;
namespace
{
@@ -242,56 +298,15 @@ WaitForEventOnHelper<LISTENER> wfeoh(const LISTENER& listener, int discriminator
namespace llcoro
{
-LLEventWithID postAndWait2(const LLSD& event,
- const LLEventPumpOrPumpName& requestPump,
- const LLEventPumpOrPumpName& replyPump0,
- const LLEventPumpOrPumpName& replyPump1,
- const LLSD& replyPump0NamePath,
- const LLSD& replyPump1NamePath)
-{
- // declare the future
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());
- LLTempBoundListener connection0(
- replyPump0.getPump().listen(name + "a",
wfeoh(boost::dcoroutines::make_callback(future), 0)));
- LLTempBoundListener connection1(
- replyPump1.getPump().listen(name + "b",
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());
- LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
- << " posting to " << requestPump.getPump().getName()
- << ": " << modevent << LL_ENDL;
- requestPump.getPump().post(modevent);
- }
- LL_DEBUGS("lleventcoro") << "postAndWait2(): coroutine " << name
- << " about to wait on LLEventPumps " << replyPump0.getPump().getName()
- << ", " << replyPump1.getPump().getName() << LL_ENDL;
- // trying to dereference ("resolve") the future makes us wait for it
- LLEventWithID value;
- {
- // instantiate Suspending to manage "current" coroutine
llcoro::Suspending suspended;
- value = *future;
- } // destroy Suspending as soon as we're back
- LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << name
- << " resuming with (" << value.first << ", " << value.second << ")"
- << LL_ENDL;
- // returning should disconnect both connections
- return value;
-}
-
LLSD errorException(const LLEventWithID& result, const std::string& desc)
{
// If the result arrived on the error pump (pump 1), instead of
diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h
index e2ce4bb193..20fc422a68 100755
--- a/indra/llcommon/lleventcoro.h
+++ b/indra/llcommon/lleventcoro.h
@@ -101,6 +101,8 @@ VoidListener<LISTENER> voidlistener(const LISTENER& listener)
return VoidListener<LISTENER>(listener);
}
+ * each distinct coroutine instance.
+ std::string listenerNameForCoro();
/**
* Yield control from a coroutine for one "mainloop" tick. If your coroutine
* runs without suspending for nontrivial time, sprinkle in calls to this
@@ -307,13 +309,13 @@ public:
*/
LLSD wait()
{
- return llcoro::waitForEventOn(mPump);
+ return ::waitForEventOn(mPump);
}
LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
const LLSD& replyPumpNamePath=LLSD())
{
- return llcoro::postAndWait(event, requestPump, mPump, replyPumpNamePath);
+ return ::postAndWait(event, requestPump, mPump, replyPumpNamePath);
}
private:
@@ -352,19 +354,19 @@ public:
/// waitForEventOn(either of our two LLEventPumps)
LLEventWithID wait()
{
- return llcoro::waitForEventOn(mPump0, mPump1);
+ return waitForEventOn(mPump0, mPump1);
}
/// errorException(wait())
LLSD waitWithException()
{
- return llcoro::errorException(wait(), std::string("Error event on ") + getName1());
+ return errorException(wait(), std::string("Error event on ") + getName1());
}
/// errorLog(wait())
LLSD waitWithLog()
{
- return llcoro::errorLog(wait(), std::string("Error event on ") + getName1());
+ return errorLog(wait(), std::string("Error event on ") + getName1());
}
LLEventWithID postAndWait(const LLSD& event,
@@ -372,7 +374,7 @@ public:
const LLSD& replyPump0NamePath=LLSD(),
const LLSD& replyPump1NamePath=LLSD())
{
- return llcoro::postAndWait2(event, requestPump, mPump0, mPump1,
+ return postAndWait2(event, requestPump, mPump0, mPump1,
replyPump0NamePath, replyPump1NamePath);
}
@@ -381,7 +383,7 @@ public:
const LLSD& replyPump0NamePath=LLSD(),
const LLSD& replyPump1NamePath=LLSD())
{
- return llcoro::errorException(postAndWait(event, requestPump,
+ return errorException(postAndWait(event, requestPump,
replyPump0NamePath, replyPump1NamePath),
std::string("Error event on ") + getName1());
}
@@ -391,7 +393,7 @@ public:
const LLSD& replyPump0NamePath=LLSD(),
const LLSD& replyPump1NamePath=LLSD())
{
- return llcoro::errorLog(postAndWait(event, requestPump,
+ return errorLog(postAndWait(event, requestPump,
replyPump0NamePath, replyPump1NamePath),
std::string("Error event on ") + getName1());
}
diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp
index 00be5035f2..b8d9d8002f 100755
--- a/indra/llcommon/tests/lleventcoro_test.cpp
+++ b/indra/llcommon/tests/lleventcoro_test.cpp
@@ -264,7 +264,8 @@ namespace tut
// Construct the coroutine instance that will run explicit_wait.
// Pass the ctor a callable that accepts the coroutine_type::self
// param passed by the library.
- boost::dcoroutines::coroutine<void()> coro(explicit_wait);
+ boost::dcoroutines::coroutine<void()>
+ coro(explicit_wait);
// Start the coroutine
coro(std::nothrow);
// When the coroutine waits for the event pump, it returns here.