Skip to content

Commit

Permalink
Fix unit test of generator_future
Browse files Browse the repository at this point in the history
  • Loading branch information
owent committed May 24, 2022
1 parent c3addcb commit 184d52b
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 16 deletions.
3 changes: 2 additions & 1 deletion include/libcopp/coroutine/callable_promise.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ class LIBCOPP_COPP_API_HEAD_ONLY callable_future {
}

~callable_future() {
while (current_handle_ && !current_handle_.promise().check_flag(promise_flag::kFinalSuspend)) {
while (current_handle_ && !current_handle_.done() &&
!current_handle_.promise().check_flag(promise_flag::kFinalSuspend)) {
current_handle_.resume();
}

Expand Down
2 changes: 1 addition & 1 deletion include/libcopp/coroutine/generator_promise.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ class LIBCOPP_COPP_API_HEAD_ONLY generator_awaitable_base : public awaitable_bas

if (caller) {
if (nullptr != context_) {
if (!context_->is_ready()) {
if (!context_->is_ready() && nullptr != caller.promise) {
error_status = caller.promise->get_status();
}

Expand Down
7 changes: 4 additions & 3 deletions sample/sample_benchmark_std_couroutine_callable_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ static void benchmark_round(int index) {
++round;
continue_flag = false;
for (auto& generator_context : g_benchmark_generator_list) {
if (generator_context) {
generator_context->set_value(round);
benchmark_generator_future_type::context_pointer_type move_context;
move_context.swap(generator_context);
if (move_context) {
move_context->set_value(round);
++real_switch_times;
continue_flag = true;
generator_context.reset();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,12 @@ static void benchmark_round(int index) {
++round;
continue_flag = false;
for (auto &generator_context : g_benchmark_generator_list) {
if (generator_context) {
generator_context->set_value(benchmark_no_trivial_message_t{round});
benchmark_generator_future_type::context_pointer_type move_context;
move_context.swap(generator_context);
if (move_context) {
move_context->set_value(benchmark_no_trivial_message_t{round});
++real_switch_times;
continue_flag = true;
generator_context.reset();
}
}
}
Expand Down
21 changes: 13 additions & 8 deletions src/libcopp/coroutine/std_coroutine_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,17 @@ LIBCOPP_COPP_API size_t promise_caller_manager::resume_callers() {
if (std::holds_alternative<handle_delegate>(callers_)) {
auto caller = std::get<handle_delegate>(callers_);
std::get<handle_delegate>(callers_) = nullptr;
if (caller.handle && !caller.handle.done() && !caller.promise->check_flag(promise_flag::kDestroying)) {
if (caller.handle && !caller.handle.done() &&
(nullptr == caller.promise || !caller.promise->check_flag(promise_flag::kDestroying))) {
caller.handle.resume();
++resume_count;
}
} else if (std::holds_alternative<multi_caller_set>(callers_)) {
multi_caller_set callers;
callers.swap(std::get<multi_caller_set>(callers_));
for (auto &caller : callers) {
if (caller.handle && !caller.handle.done() && !caller.promise->check_flag(promise_flag::kDestroying)) {
if (caller.handle && !caller.handle.done() &&
(nullptr == caller.promise || !caller.promise->check_flag(promise_flag::kDestroying))) {
type_erased_handle_type handle = caller.handle;
handle.resume();
++resume_count;
Expand All @@ -115,14 +117,15 @@ LIBCOPP_COPP_API size_t promise_caller_manager::resume_callers() {

// The promise object may be destroyed after first caller.resume()
if (unique_caller.handle && !unique_caller.handle.done() &&
!unique_caller.promise->check_flag(promise_flag::kDestroying)) {
(nullptr == unique_caller.promise || !unique_caller.promise->check_flag(promise_flag::kDestroying))) {
unique_caller.handle.resume();
++resume_count;
}

if (multiple_callers) {
for (auto &caller : *multiple_callers) {
if (caller.handle && !caller.handle.done() && !caller.promise->check_flag(promise_flag::kDestroying)) {
if (caller.handle && !caller.handle.done() &&
(nullptr == caller.promise || !caller.promise->check_flag(promise_flag::kDestroying))) {
type_erased_handle_type handle = caller.handle;
handle.resume();
++resume_count;
Expand Down Expand Up @@ -202,8 +205,9 @@ LIBCOPP_COPP_API void promise_base_type::resume_waiting(handle_delegate current_
if (waiting_delegate.handle && !waiting_delegate.handle.done()) {
current_waiting_ = nullptr;
// Prevent the waiting coroutine remuse this again.
assert(waiting_delegate.promise);
waiting_delegate.promise->remove_caller(current_delegate, inherit_status);
if (nullptr != waiting_delegate.promise) {
waiting_delegate.promise->remove_caller(current_delegate, inherit_status);
}
waiting_delegate.handle.resume();
}
}
Expand All @@ -219,8 +223,9 @@ LIBCOPP_COPP_API void promise_base_type::add_caller(handle_delegate delegate) no
}

LIBCOPP_COPP_API void promise_base_type::remove_caller(handle_delegate delegate, bool inherit_status) noexcept {
if (caller_manager_.remove_caller(delegate) && inherit_status && nullptr != delegate.promise &&
get_status() < promise_status::kDone && delegate.promise->get_status() > promise_status::kDone) {
bool remove_caller_success = caller_manager_.remove_caller(delegate);
if (remove_caller_success && inherit_status && nullptr != delegate.promise && get_status() < promise_status::kDone &&
delegate.promise->get_status() > promise_status::kDone) {
set_status(delegate.promise->get_status());
}
}
Expand Down

0 comments on commit 184d52b

Please sign in to comment.