diff options
| -rw-r--r-- | indra/llcommon/tests/workqueue_test.cpp | 49 | ||||
| -rw-r--r-- | indra/llcommon/workqueue.h | 38 | 
2 files changed, 68 insertions, 19 deletions
diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp index b69df49d33..bea3ad911b 100644 --- a/indra/llcommon/tests/workqueue_test.cpp +++ b/indra/llcommon/tests/workqueue_test.cpp @@ -20,7 +20,10 @@  // external library headers  // other Linden headers  #include "../test/lltut.h" +#include "../test/catch_and_store_what_in.h"  #include "llcond.h" +#include "llcoros.h" +#include "lleventcoro.h"  #include "llstring.h"  #include "stringize.h" @@ -177,4 +180,50 @@ namespace tut          main.runOne();          ensure_equals("failed to run both lambdas", observe, "queue;main");      } + +    template<> template<> +    void object::test<6>() +    { +        set_test_name("waitForResult"); +        std::string stored; +        // Try to call waitForResult() on this thread's main coroutine. It +        // should throw because the main coroutine must service the queue. +        auto what{ catch_what<WorkQueue::Error>( +                [this, &stored](){ stored = queue.waitForResult( +                        [](){ return "should throw"; }); }) }; +        ensure("lambda should not have run", stored.empty()); +        ensure_not("waitForResult() should have thrown", what.empty()); +        ensure(STRINGIZE("should mention waitForResult: " << what), +               what.find("waitForResult") != std::string::npos); + +        // Call waitForResult() on a coroutine, with a string result. +        LLCoros::instance().launch( +            "waitForResult string", +            [this, &stored]() +            { stored = queue.waitForResult( +                    [](){ return "string result"; }); }); +        llcoro::suspend(); +        // Nothing will have happened yet because, even if the coroutine did +        // run immediately, all it did was to queue the inner lambda on +        // 'queue'. Service it. +        queue.runOne(); +        llcoro::suspend(); +        ensure_equals("bad waitForResult return", stored, "string result"); + +        // Call waitForResult() on a coroutine, with a void callable. +        stored.clear(); +        bool done = false; +        LLCoros::instance().launch( +            "waitForResult void", +            [this, &stored, &done]() +            { +                queue.waitForResult([&stored](){ stored = "ran"; }); +                done = true; +            }); +        llcoro::suspend(); +        queue.runOne(); +        llcoro::suspend(); +        ensure_equals("didn't run coroutine", stored, "ran"); +        ensure("void waitForResult() didn't return", done); +    }  } // namespace tut diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 42f5d78ba3..7dbc735c6d 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -93,6 +93,25 @@ namespace LL          }          /** +         * Post work to be run at a specified time to another WorkQueue, which +         * may or may not still exist and be open. Return true if we were able +         * to post. +         */ +        template <typename CALLABLE> +        static bool postMaybe(weak_t target, const TimePoint& time, CALLABLE&& callable); + +        /** +         * Post work to another WorkQueue, which may or may not still exist +         * and be open. Return true if we were able to post. +         */ +        template <typename CALLABLE> +        static bool postMaybe(weak_t target, CALLABLE&& callable) +        { +            return postMaybe(target, TimePoint::clock::now(), +                             std::forward<CALLABLE>(callable)); +        } + +        /**           * Launch a callable returning bool that will trigger repeatedly at           * specified interval, until the callable returns false.           * @@ -137,25 +156,6 @@ namespace LL          }          /** -         * Post work to be run at a specified time to another WorkQueue, which -         * may or may not still exist and be open. Return true if we were able -         * to post. -         */ -        template <typename CALLABLE> -        static bool postMaybe(weak_t target, const TimePoint& time, CALLABLE&& callable); - -        /** -         * Post work to another WorkQueue, which may or may not still exist -         * and be open. Return true if we were able to post. -         */ -        template <typename CALLABLE> -        static bool postMaybe(weak_t target, CALLABLE&& callable) -        { -            return postMaybe(target, TimePoint::clock::now(), -                             std::forward<CALLABLE>(callable)); -        } - -        /**           * Post work to another WorkQueue to be run at a specified time,           * blocking the calling coroutine until then, returning the result to           * caller on completion.  | 
