summaryrefslogtreecommitdiff
path: root/indra/llcommon/lleventcoro.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lleventcoro.h')
-rwxr-xr-xindra/llcommon/lleventcoro.h174
1 files changed, 34 insertions, 140 deletions
diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h
index f9447eaa96..20fc422a68 100755
--- a/indra/llcommon/lleventcoro.h
+++ b/indra/llcommon/lleventcoro.h
@@ -29,8 +29,6 @@
#if ! defined(LL_LLEVENTCORO_H)
#define LL_LLEVENTCORO_H
-#include <boost/dcoroutine/coroutine.hpp>
-#include <boost/dcoroutine/future.hpp>
#include <boost/optional.hpp>
#include <string>
#include <stdexcept>
@@ -103,21 +101,8 @@ VoidListener<LISTENER> voidlistener(const LISTENER& listener)
return VoidListener<LISTENER>(listener);
}
- /// Implementation for listenerNameForCoro(), see below
- LL_COMMON_API std::string listenerNameForCoroImpl(const void* self_id);
-
- * can't know the type of 'self', because it depends on the coroutine
- * body's signature. So we cast its address to void*, looking for distinct
- * pointer values. Yes, that means that an early coroutine could cache a
- * value here, then be destroyed, only to be supplanted by a later
- * coroutine (of the same or different type), and we'll end up
- * "recognizing" the second one and reusing the listener name -- but
- * that's okay, since it won't collide with any listener name used by the
- * earlier coroutine since that earlier coroutine no longer exists.
- std::string listenerNameForCoro(COROUTINE_SELF& self)
- {
- return listenerNameForCoroImpl(self.get_id());
- }
+ * 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
@@ -131,7 +116,7 @@ void yield();
* convenience: the difference between this function and the sequence
* @code
* requestPump.post(myEvent);
- * LLSD reply = waitForEventOn(self, replyPump);
+ * LLSD reply = waitForEventOn(replyPump);
* @endcode
* is that the sequence above fails if the reply is posted immediately on
* @a replyPump, that is, before <tt>requestPump.post()</tt> returns. In the
@@ -173,51 +158,16 @@ void yield();
* @a replyPumpNamePath specifies the entry in the lowest-level structure in
* @a event into which to store <tt>replyPump.getName()</tt>.
*/
-template <typename SELF>
-LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& requestPump,
- const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD())
-{
- // declare the future
- boost::dcoroutines::future<LLSD> future(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(self));
- 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(*future);
- LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName
- << " resuming with " << value << LL_ENDL;
- // returning should disconnect the connection
- return value;
-}
+LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+ const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD());
/// Wait for the next event on the specified LLEventPump. Pass either the
/// LLEventPump& or its string name.
-template <typename SELF>
-LLSD waitForEventOn(SELF& self, const LLEventPumpOrPumpName& pump)
+inline
+LLSD waitForEventOn(const LLEventPumpOrPumpName& pump)
{
// This is now a convenience wrapper for postAndWait().
- return postAndWait(self, LLSD(), LLEventPumpOrPumpName(), pump);
+ return postAndWait(LLSD(), LLEventPumpOrPumpName(), pump);
}
} // namespace llcoro
@@ -248,7 +198,7 @@ namespace llcoro
* I'd have preferred to overload the name postAndWait() for both signatures.
* But consider the following ambiguous call:
* @code
- * postAndWait(self, LLSD(), requestPump, replyPump, "someString");
+ * postAndWait(LLSD(), requestPump, replyPump, "someString");
* @endcode
* "someString" could be converted to either LLSD (@a replyPumpNamePath for
* the single-pump function) or LLEventOrPumpName (@a replyPump1 for two-pump
@@ -257,69 +207,29 @@ namespace llcoro
* It seems less burdensome to write postAndWait2() than to write either
* LLSD("someString") or LLEventOrPumpName("someString").
*/
-template <typename SELF>
-LLEventWithID postAndWait2(SELF& self, const LLSD& event,
+LLEventWithID postAndWait2(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
const LLEventPumpOrPumpName& replyPump0,
const LLEventPumpOrPumpName& replyPump1,
const LLSD& replyPump0NamePath=LLSD(),
- const LLSD& replyPump1NamePath=LLSD())
-{
- // declare the future
- boost::dcoroutines::future<LLEventWithID> future(self);
- // either callback will assign a value to this future; listen on
- // each specified LLEventPump with a callback
- std::string name(LLEventDetail::listenerNameForCoro(self));
- 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(*future);
- LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << name
- << " resuming with (" << value.first << ", " << value.second << ")"
- << LL_ENDL;
- // returning should disconnect both connections
- return value;
-}
+ const LLSD& replyPump1NamePath=LLSD());
/**
* Wait for the next event on either of two specified LLEventPumps.
*/
-template <typename SELF>
+inline
LLEventWithID
-waitForEventOn(SELF& self,
- const LLEventPumpOrPumpName& pump0, const LLEventPumpOrPumpName& pump1)
+waitForEventOn(const LLEventPumpOrPumpName& pump0, const LLEventPumpOrPumpName& pump1)
{
// This is now a convenience wrapper for postAndWait2().
- return postAndWait2(self, LLSD(), LLEventPumpOrPumpName(), pump0, pump1);
+ return postAndWait2(LLSD(), LLEventPumpOrPumpName(), pump0, pump1);
}
/**
* Helper for the two-pump variant of waitForEventOn(), e.g.:
*
* @code
- * LLSD reply = errorException(waitForEventOn(self, replyPump, errorPump),
+ * LLSD reply = errorException(waitForEventOn(replyPump, errorPump),
* "error response from login.cgi");
* @endcode
*
@@ -396,26 +306,16 @@ public:
/**
* Wait for an event on this LLEventPump.
- *
- * @note
- * The other major usage pattern we considered was to bind @c self at
- * LLCoroEventPump construction time, which would avoid passing the
- * parameter to each wait() call. But if we were going to bind @c self as
- * a class member, we'd need to specify a class template parameter
- * indicating its type. The big advantage of passing it to the wait() call
- * is that the type can be implicit.
*/
- template <typename SELF>
- LLSD wait(SELF& self)
+ LLSD wait()
{
- return llcoro::waitForEventOn(mPump);
+ return ::waitForEventOn(mPump);
}
- template <typename SELF>
- LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& requestPump,
+ 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:
@@ -451,55 +351,49 @@ public:
/// request pump 1
LLEventPump& getPump1() { return mPump1; }
- /// waitForEventOn(self, either of our two LLEventPumps)
- template <typename SELF>
- LLEventWithID wait(SELF& self)
+ /// waitForEventOn(either of our two LLEventPumps)
+ LLEventWithID wait()
{
- return llcoro::waitForEventOn(mPump0, mPump1);
+ return waitForEventOn(mPump0, mPump1);
}
- /// errorException(wait(self))
- template <typename SELF>
- LLSD waitWithException(SELF& self)
+ /// 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(self))
- template <typename SELF>
- LLSD waitWithLog(SELF& self)
+ /// errorLog(wait())
+ LLSD waitWithLog()
{
- return llcoro::errorLog(wait(), std::string("Error event on ") + getName1());
+ return errorLog(wait(), std::string("Error event on ") + getName1());
}
- template <typename SELF>
- LLEventWithID postAndWait(SELF& self, const LLSD& event,
+ LLEventWithID postAndWait(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
const LLSD& replyPump0NamePath=LLSD(),
const LLSD& replyPump1NamePath=LLSD())
{
- return llcoro::postAndWait2(event, requestPump, mPump0, mPump1,
+ return postAndWait2(event, requestPump, mPump0, mPump1,
replyPump0NamePath, replyPump1NamePath);
}
- template <typename SELF>
- LLSD postAndWaitWithException(SELF& self, const LLSD& event,
+ LLSD postAndWaitWithException(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
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());
}
- template <typename SELF>
- LLSD postAndWaitWithLog(SELF& self, const LLSD& event,
+ LLSD postAndWaitWithLog(const LLSD& event,
const LLEventPumpOrPumpName& requestPump,
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());
}