summaryrefslogtreecommitdiff
path: root/indra/llcommon/lleventcoro.cpp
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2015-07-10 19:34:20 -0400
committerNat Goodspeed <nat@lindenlab.com>2015-07-10 19:34:20 -0400
commit391d9a367b61fe8098ffff0d6a6a54f65f0a3a9e (patch)
tree6afd2069680a87d0f9ec7a35e8abbcaf720796aa /indra/llcommon/lleventcoro.cpp
parent9809f59fa93952d066e61223b4c6d1895a43e4dd (diff)
parentefa9a0f99c17b2b937120bcad6e3d45944122ed9 (diff)
Merge restore of more selfless changes
Diffstat (limited to 'indra/llcommon/lleventcoro.cpp')
-rwxr-xr-xindra/llcommon/lleventcoro.cpp113
1 files changed, 98 insertions, 15 deletions
diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp
index 019b5641b7..e400a052a1 100755
--- a/indra/llcommon/lleventcoro.cpp
+++ b/indra/llcommon/lleventcoro.cpp
@@ -34,12 +34,14 @@
#include <map>
// std headers
// external library headers
+#include <boost/dcoroutine/coroutine.hpp>
+#include <boost/dcoroutine/future.hpp>
// other Linden headers
#include "llsdserialize.h"
#include "llerror.h"
#include "llcoros.h"
-namespace
+std::string LLEventDetail::listenerNameForCoro()
{
/**
@@ -57,26 +59,15 @@ namespace
*/
std::string listenerNameForCoro()
{
- // First, if this coroutine was launched by LLCoros::launch(), find that name.
- std::string name(LLCoros::instance().getNameByID(self_id));
+ // If this coroutine was launched by LLCoros::launch(), find that name.
+ std::string name(LLCoros::instance().getName());
if (! name.empty())
{
return name;
}
- // Apparently this coroutine wasn't launched by LLCoros::launch(). Check
- // whether we have a memo for this self_id.
- typedef std::map<const void*, std::string> MapType;
- static MapType memo;
- MapType::const_iterator found = memo.find(self_id);
- if (found != memo.end())
- {
- // this coroutine instance has called us before, reuse same name
- return found->second;
- }
// this is the first time we've been called for this coroutine instance
name = LLEventPump::inventName("coro");
- memo[self_id] = name;
- LL_INFOS("LLEventCoro") << "listenerNameForCoroImpl(" << self_id << "): inventing coro name '"
+ LL_INFOS("LLEventCoro") << "listenerNameForCoro(): inventing coro name '"
<< name << "'" << LL_ENDL;
return name;
}
@@ -152,6 +143,98 @@ void storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)
*pdest = value;
}
+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(LLEventDetail::listenerNameForCoro());
+ LLTempBoundListener connection(
+ replyPump.getPump().listen(listenerName,
+ voidlistener(boost::dcoroutines::make_callback(future))));
+ // skip the "post" part if requestPump is default-constructed
+ if (requestPump)
+ {
+ // If replyPumpNamePath is non-empty, store the replyPump name in the
+ // request event.
+ LLSD modevent(event);
+ LLEventDetail::storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());
+ LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
+ << " posting to " << requestPump.getPump().getName()
+ << LL_ENDL;
+
+ // *NOTE:Mani - Removed because modevent could contain user's hashed passwd.
+ // << ": " << modevent << LL_ENDL;
+ requestPump.getPump().post(modevent);
+ }
+ LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
+ << " about to wait on LLEventPump " << replyPump.getPump().getName()
+ << LL_ENDL;
+ // trying to dereference ("resolve") the future makes us wait for it
+ LLSD value;
+ {
+ // instantiate Suspending to manage the "current" coroutine
+ LLCoros::Suspending suspended;
+ value = *future;
+ } // destroy Suspending as soon as we're back
+ LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
+ << " resuming with " << value << LL_ENDL;
+ // returning should disconnect the connection
+ 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()