17 #include <type_traits> 50 template <
class ExecutorRef>
81 auto signaled =
start;
88 [&](
auto)
noexcept { signals += 1000; },
89 [&]() { signals += 10; });
92 <<
"expected that the value and done signals are recorded once and the value signal did not drift much";
94 std::chrono::duration_cast<std::chrono::milliseconds>((signaled -
start))
102 op::get<std::chrono::system_clock::time_point>;
105 std::chrono::duration_cast<std::chrono::milliseconds>((signaled -
start))
112 std::vector<std::string>
times;
113 std::atomic<int> pushed{0};
114 auto push = [&](
int time) {
116 times.push_back(folly::to<std::string>(
time));
127 while (pushed.load() < 4) {
132 <<
"expected that the items were pushed in time order not insertion order";
143 EXPECT_THAT(done,
Eq(
true)) <<
"exptected that both calls to now() complete";
150 [&](
auto) { signals += 100; },
151 [&](
auto)
noexcept { signals += 1000; },
152 [&]() { signals += 10; });
155 <<
"the value and done signals are recorded once";
159 auto v = nt_ |
op::transform([](
auto) {
return 42; }) | op::get<int>;
161 EXPECT_THAT(
v,
Eq(42)) <<
"expected that the result would be different";
166 std::function<void(::folly::pushmi::any_executor_ref<> exec)> recurse; 167 recurse = [&](::folly::pushmi::any_executor_ref<> nt) { 170 nt | op::submit(recurse); 172 nt_ | op::blocking_submit([&](auto nt) { recurse(nt); }); 174 EXPECT_THAT(counter, Eq(0)) 175 << "expected that all nested submissions complete"; 178 TEST_F(NewthreadExecutor, StaticDerecursion) { 179 int counter = 100'000;
184 <<
"expected that all nested submissions complete";
188 std::vector<std::string>
values;
197 sender |
op::on([&]() {
return nt_; }) |
199 [&](
auto v) { values.push_back(folly::to<std::string>(
v)); }));
202 <<
"expected that only the first item was pushed";
206 std::vector<std::string>
values;
217 [&](
auto v) { values.push_back(folly::to<std::string>(
v)); }));
220 <<
"expected that only the first item was pushed";
TEST_F(NewthreadExecutor, BlockingSubmitNow)
requires Invocable< ExecutorFactory & > &&Executor< invoke_result_t< ExecutorFactory & > > &&ConcurrentSequence< invoke_result_t< ExecutorFactory & > > auto strands(ExecutorFactory ef)
auto on_value(Fns...fns) -> on_value_fn< Fns... >
internal::EqMatcher< T > Eq(T x)
void operator()(ExecutorRef exec)
std::chrono::steady_clock::time_point now()
requires E e noexcept(noexcept(s.error(std::move(e))))
auto make_time(mi::time_source<> &t, NT &ex)
PUSHMI_INLINE_VAR constexpr detail::transform_fn transform
~NewthreadExecutor() override
PUSHMI_INLINE_VAR constexpr detail::via_fn via
internal::LtMatcher< Rhs > Lt(Rhs x)
PUSHMI_INLINE_VAR constexpr detail::blocking_submit_fn blocking_submit
new_thread_executor new_thread()
mi::invoke_result_t< decltype(make_time), mi::time_source<> &, NT & > TNT
PUSHMI_INLINE_VAR constexpr detail::submit_at_fn submit_at
#define EXPECT_THAT(value, matcher)
std::atomic< int > counter
PUSHMI_INLINE_VAR constexpr __adl::set_value_fn set_value
decltype(folly::pushmi::invoke(std::declval< F >(), std::declval< As >()...)) invoke_result_t
Future< Unit > times(const int n, F &&thunk)
PUSHMI_INLINE_VAR constexpr detail::submit_after_fn submit_after
internal::ElementsAreMatcher< ::testing::tuple<> > ElementsAre()
requires Invocable< ExecutorFactory & > &&Executor< invoke_result_t< ExecutorFactory & > > &&NeverBlocking< invoke_result_t< ExecutorFactory & > > auto make(NF nf, ExecutorFactory ef)
PUSHMI_INLINE_VAR constexpr detail::on_fn on
std::chrono::nanoseconds time()
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::make_single_sender_fn make_single_sender
std::vector< int > values(1'000)
PUSHMI_INLINE_VAR constexpr __adl::set_done_fn set_done