Skip to content

Commit

Permalink
防止 awaitable_detached 在 完全 detach 模式下吞异常
Browse files Browse the repository at this point in the history
  • Loading branch information
microcai committed Oct 18, 2024
1 parent bd165e8 commit 84cf6e6
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions include/ucoro/awaitable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ namespace ucoro
value_.template emplace<std::exception_ptr>(std::current_exception());
}

bool has_exception() const
{
return std::holds_alternative<std::exception_ptr>(value_);
}

std::exception_ptr get_exception_ptr()
{
return std::get<std::exception_ptr>(value_);
}

std::variant<std::exception_ptr, T> value_{nullptr};
};

Expand All @@ -153,6 +163,16 @@ namespace ucoro
{
exception_ = std::current_exception();
}

bool has_exception() const
{
return exception_.operator bool();
}

std::exception_ptr get_exception_ptr()
{
return exception_;
}
};

//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -185,6 +205,16 @@ namespace ucoro
// 如果 continuation_ 为空,则说明 .detach() 没有被 co_await
// 因此,awaitable_detached 对象其实已经析构
// 所以必须主动调用 destroy() 以免内存泄漏.
if (final_coro_handle.promise().has_exception())
{
// 并且,如果协程处于 .detach() 而没有被 co_await
// 则异常一直存储在 promise 里,并没有代码会去调用他的 await_resume() 重抛异常
// 所以这里重新抛出来,避免有被静默吞并的异常
auto exception_ptr = final_coro_handle.promise().get_exception_ptr();
final_coro_handle.destroy();
std::rethrow_exception(exception_ptr);
for(;;); // 不可达
}
final_coro_handle.destroy();
return std::noop_coroutine();
}
Expand Down

0 comments on commit 84cf6e6

Please sign in to comment.