SL-16220: Add tests for WorkQueue::waitForResult(), void & non-void.

master
Nat Goodspeed 2021-10-27 15:31:54 -04:00
parent f06765cba8
commit 8b16ecb9cf
2 changed files with 68 additions and 19 deletions

View File

@ -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

View File

@ -92,6 +92,25 @@ namespace LL
post(TimePoint::clock::now(), std::move(callable));
}
/**
* 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.
@ -136,25 +155,6 @@ namespace LL
std::move(callable), std::move(callback));
}
/**
* 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