Skip to content

Commit

Permalink
task_detach_start
Browse files Browse the repository at this point in the history
  • Loading branch information
kelbon committed Aug 9, 2024
1 parent b3fc8d8 commit dbf8a95
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/kelcoro/noexcept_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ struct noexcept_task : enable_resource_deduction {
return std::exchange(handle_, nullptr);
}

// postcondition: empty(), task result ignored
// returns released task handle (task will delete itself when ended)
handle_type start_and_detach(bool stop_at_end = false) {
if (!handle_)
return nullptr;
handle_type h = std::exchange(handle_, nullptr);
// task resumes itself at end and destroys itself or just stops with noop_coroutine
h.promise().who_waits = stop_at_end ? std::noop_coroutine() : std::coroutine_handle<>(h);
h.resume();
return h;
}

// blocking
result_type get() noexcept {
assert(!empty());
Expand Down
12 changes: 12 additions & 0 deletions include/kelcoro/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ struct task : enable_resource_deduction {
return std::exchange(handle_, nullptr);
}

// postcondition: empty(), task result ignored
// returns released task handle (task will delete itself when ended)
handle_type start_and_detach(bool stop_at_end = false) {
if (!handle_)
return nullptr;
handle_type h = std::exchange(handle_, nullptr);
// task resumes itself at end and destroys itself or just stops with noop_coroutine
h.promise().who_waits = stop_at_end ? std::noop_coroutine() : std::coroutine_handle<>(h);
h.resume();
return h;
}

// blocking
result_type get() {
assert(!empty());
Expand Down
24 changes: 24 additions & 0 deletions tests/test_coroutines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,29 @@ TEST(task_blocking_wait_noexcept) {
return error_count;
}

TEST(task_start_and_detach) {
std::atomic_bool flag = false;
dd::task task = [](std::atomic_bool& flag) -> dd::task<void> {
(void)co_await dd::jump_on(dd::new_thread_executor);
flag.exchange(true);
(void)co_await dd::jump_on(dd::new_thread_executor);
dd::scope_exit e = [&] { flag.notify_one(); };
}(flag);
task.start_and_detach();
flag.wait(false);
int x = 0;
dd::task task2 = [](int& x) -> dd::task<void> {
x = 42;
co_return;
}(x);
error_if(x != 0);
std::coroutine_handle h = task2.start_and_detach(/*stop_at_end=*/true);
error_if(x != 42);
error_if(!h.done());
h.destroy();
return error_count;
}

TEST(task_blocking_wait) {
error_if(do_smth().get() != "hello from task");
return error_count;
Expand Down Expand Up @@ -554,6 +577,7 @@ int main() {
ec += TESTtask_blocking_wait();
ec += TESTtask_with_exception();
ec += TESTtask_blocking_wait_noexcept();
ec += TESTtask_start_and_detach();
return ec;
}
#else
Expand Down

0 comments on commit dbf8a95

Please sign in to comment.