feat: Async framework submit on strand/ctx (#2751)

This commit is contained in:
Alex Kremer
2025-11-04 19:14:31 +00:00
committed by GitHub
parent d6ab2cc1e4
commit 6d79dd6b2b
14 changed files with 296 additions and 110 deletions

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include "util/MockAssert.hpp"
#include "util/Profiler.hpp"
#include "util/async/Operation.hpp"
#include "util/async/context/BasicExecutionContext.hpp"
@@ -32,12 +33,13 @@
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>
using namespace util::async;
using ::testing::Types;
template <typename T>
struct ExecutionContextTests : public ::testing::Test {
struct ExecutionContextTests : common::util::WithMockAssertNoThrow {
using ExecutionContextType = T;
ExecutionContextType ctx{2};
@@ -238,6 +240,32 @@ TYPED_TEST(ExecutionContextTests, repeatingOperationForceInvoke)
EXPECT_EQ(callCount, 0uz);
}
TYPED_TEST(ExecutionContextTests, submit)
{
EXPECT_CLIO_ASSERT_FAIL(this->ctx.submit([] -> void { throw 0; }));
std::atomic_uint32_t count = 0;
std::binary_semaphore sem{0};
static constexpr auto kNUM_SUBMISSIONS = 1024;
for (auto i = 1; i <= kNUM_SUBMISSIONS; ++i) {
if (i == kNUM_SUBMISSIONS) {
this->ctx.submit([&count, &sem] {
++count;
sem.release();
});
} else {
this->ctx.submit([&count] { ++count; });
}
}
sem.acquire();
// order is not guaranteed (see `strandSubmit` below)
ASSERT_EQ(count, static_cast<size_t>(kNUM_SUBMISSIONS));
}
TYPED_TEST(ExecutionContextTests, strandMove)
{
auto strand = this->ctx.makeStrand();
@@ -328,6 +356,35 @@ TYPED_TEST(ExecutionContextTests, strandedRepeatingOperationForceInvoke)
EXPECT_EQ(callCount, 0uz);
}
TYPED_TEST(ExecutionContextTests, strandSubmit)
{
auto strand = this->ctx.makeStrand();
EXPECT_CLIO_ASSERT_FAIL(strand.submit([] -> void { throw 0; }));
std::vector<int> results;
std::binary_semaphore sem{0};
static constexpr auto kNUM_SUBMISSIONS = 1024;
for (auto i = 1; i <= kNUM_SUBMISSIONS; ++i) {
if (i == kNUM_SUBMISSIONS) {
strand.submit([&results, &sem, i] {
results.push_back(i);
sem.release();
});
} else {
strand.submit([&results, i] { results.push_back(i); });
}
}
sem.acquire();
ASSERT_EQ(results.size(), static_cast<size_t>(kNUM_SUBMISSIONS));
for (int i = 0; i < kNUM_SUBMISSIONS; ++i) {
EXPECT_EQ(results[i], i + 1);
}
}
TYPED_TEST(AsyncExecutionContextTests, executeAutoAborts)
{
auto value = 0;