diff options
| -rwxr-xr-x | indra/llcommon/llcoros.cpp | 4 | ||||
| -rwxr-xr-x | indra/llcommon/llcoros.h | 12 | ||||
| -rwxr-xr-x | indra/llcommon/lleventcoro.cpp | 127 | ||||
| -rwxr-xr-x | indra/llcommon/lleventcoro.h | 18 | ||||
| -rwxr-xr-x | indra/llcommon/tests/lleventcoro_test.cpp | 3 | 
5 files changed, 67 insertions, 97 deletions
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 6cca5e7c60..d76401d01b 100755 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -61,7 +61,7 @@ LLCoros::coro::self& LLCoros::get_self()      return *current->mSelf;  } -LLCoros::Suspending::Suspending(): +llcoro::Suspending::Suspending():      mSuspended(LLCoros::sCurrentCoro.get())  {      // Revert mCurrentCoro to the value it had at the moment we last switched @@ -69,7 +69,7 @@ LLCoros::Suspending::Suspending():      LLCoros::sCurrentCoro.reset(mSuspended->mPrev);  } -LLCoros::Suspending::~Suspending() +llcoro::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 05bd87dc3c..56eed8cafe 100755 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -144,18 +144,6 @@ 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 a37b87f085..66cc7cada0 100755 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -41,7 +41,7 @@  #include "llerror.h"  #include "llcoros.h" -std::string LLEventDetail::listenerNameForCoro() +namespace  {  /** @@ -143,14 +143,24 @@ void storeToLLSDPath(LLSD& dest, const LLSD& rawPath, const LLSD& value)      *pdest = value;  } -LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump, +} // 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)  {      // 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()); +    std::string listenerName(listenerNameForCoro());      LLTempBoundListener connection(          replyPump.getPump().listen(listenerName,                                     voidlistener(boost::dcoroutines::make_callback(future)))); @@ -160,7 +170,7 @@ LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,          // If replyPumpNamePath is non-empty, store the replyPump name in the          // request event.          LLSD modevent(event); -        LLEventDetail::storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName()); +        storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName());          LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName                                   << " posting to " << requestPump.getPump().getName()                                   << LL_ENDL; @@ -176,7 +186,7 @@ LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,      LLSD value;      {          // instantiate Suspending to manage the "current" coroutine -        LLCoros::Suspending suspended; +        llcoro::Suspending suspended;          value = *future;      } // destroy Suspending as soon as we're back      LL_DEBUGS("lleventcoro") << "postAndWait(): coroutine " << listenerName @@ -185,72 +195,6 @@ LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,      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  { @@ -298,15 +242,56 @@ 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 20fc422a68..e2ce4bb193 100755 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -101,8 +101,6 @@ 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 @@ -309,13 +307,13 @@ public:       */      LLSD wait()      { -        return ::waitForEventOn(mPump); +        return llcoro::waitForEventOn(mPump);      }      LLSD postAndWait(const LLSD& event, const LLEventPumpOrPumpName& requestPump,                       const LLSD& replyPumpNamePath=LLSD())      { -        return ::postAndWait(event, requestPump, mPump, replyPumpNamePath); +        return llcoro::postAndWait(event, requestPump, mPump, replyPumpNamePath);      }  private: @@ -354,19 +352,19 @@ public:      /// waitForEventOn(either of our two LLEventPumps)      LLEventWithID wait()      { -        return waitForEventOn(mPump0, mPump1); +        return llcoro::waitForEventOn(mPump0, mPump1);      }      /// errorException(wait())      LLSD waitWithException()      { -        return errorException(wait(), std::string("Error event on ") + getName1()); +        return llcoro::errorException(wait(), std::string("Error event on ") + getName1());      }      /// errorLog(wait())      LLSD waitWithLog()      { -        return errorLog(wait(), std::string("Error event on ") + getName1()); +        return llcoro::errorLog(wait(), std::string("Error event on ") + getName1());      }      LLEventWithID postAndWait(const LLSD& event, @@ -374,7 +372,7 @@ public:                                const LLSD& replyPump0NamePath=LLSD(),                                const LLSD& replyPump1NamePath=LLSD())      { -        return postAndWait2(event, requestPump, mPump0, mPump1, +        return llcoro::postAndWait2(event, requestPump, mPump0, mPump1,                                      replyPump0NamePath, replyPump1NamePath);      } @@ -383,7 +381,7 @@ public:                                    const LLSD& replyPump0NamePath=LLSD(),                                    const LLSD& replyPump1NamePath=LLSD())      { -        return errorException(postAndWait(event, requestPump, +        return llcoro::errorException(postAndWait(event, requestPump,                                                    replyPump0NamePath, replyPump1NamePath),                                        std::string("Error event on ") + getName1());      } @@ -393,7 +391,7 @@ public:                              const LLSD& replyPump0NamePath=LLSD(),                              const LLSD& replyPump1NamePath=LLSD())      { -        return errorLog(postAndWait(event, requestPump, +        return llcoro::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 b8d9d8002f..00be5035f2 100755 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -264,8 +264,7 @@ 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.  | 
