|
27 | 27 | #include <type_traits> |
28 | 28 | #include <optional> |
29 | 29 |
|
| 30 | +namespace drogon |
| 31 | +{ |
| 32 | +struct CancelHandle; |
| 33 | +using CancelHandlePtr = std::shared_ptr<CancelHandle>; |
| 34 | + |
| 35 | +struct CancelHandle |
| 36 | +{ |
| 37 | + static CancelHandlePtr create(); |
| 38 | + |
| 39 | + virtual void cancel() = 0; |
| 40 | + virtual bool isCancelRequested() = 0; |
| 41 | + virtual void registerCancelCallback(std::function<void()> callback) = 0; |
| 42 | +}; |
| 43 | + |
| 44 | +class TaskCancelledException final : public std::runtime_error |
| 45 | +{ |
| 46 | + public: |
| 47 | + using std::runtime_error::runtime_error; |
| 48 | +}; |
| 49 | +} // namespace drogon |
| 50 | + |
30 | 51 | namespace drogon |
31 | 52 | { |
32 | 53 | namespace internal |
@@ -596,6 +617,30 @@ struct [[nodiscard]] TimerAwaiter : CallbackAwaiter<void> |
596 | 617 | double delay_; |
597 | 618 | }; |
598 | 619 |
|
| 620 | +struct [[nodiscard]] CancellableTimeAwaiter : CallbackAwaiter<void> |
| 621 | +{ |
| 622 | + CancellableTimeAwaiter(trantor::EventLoop *loop, |
| 623 | + const std::chrono::duration<double> &delay, |
| 624 | + CancelHandlePtr cancelHandle) |
| 625 | + : CancellableTimeAwaiter(loop, delay.count(), std::move(cancelHandle)) |
| 626 | + { |
| 627 | + } |
| 628 | + |
| 629 | + CancellableTimeAwaiter(trantor::EventLoop *loop, |
| 630 | + double delay, |
| 631 | + CancelHandlePtr cancelHandle) |
| 632 | + : loop_(loop), delay_(delay), cancelHandle_(std::move(cancelHandle)) |
| 633 | + { |
| 634 | + } |
| 635 | + |
| 636 | + void await_suspend(std::coroutine_handle<> handle); |
| 637 | + |
| 638 | + private: |
| 639 | + trantor::EventLoop *loop_; |
| 640 | + double delay_; |
| 641 | + CancelHandlePtr cancelHandle_; |
| 642 | +}; |
| 643 | + |
599 | 644 | struct [[nodiscard]] LoopAwaiter : CallbackAwaiter<void> |
600 | 645 | { |
601 | 646 | LoopAwaiter(trantor::EventLoop *workLoop, |
@@ -684,6 +729,15 @@ inline internal::TimerAwaiter sleepCoro(trantor::EventLoop *loop, |
684 | 729 | return {loop, delay}; |
685 | 730 | } |
686 | 731 |
|
| 732 | +inline internal::CancellableTimeAwaiter sleepCoro( |
| 733 | + trantor::EventLoop *loop, |
| 734 | + double delay, |
| 735 | + CancelHandlePtr cancelHandle) noexcept |
| 736 | +{ |
| 737 | + assert(loop); |
| 738 | + return {loop, delay, std::move(cancelHandle)}; |
| 739 | +} |
| 740 | + |
687 | 741 | inline internal::LoopAwaiter queueInLoopCoro( |
688 | 742 | trantor::EventLoop *workLoop, |
689 | 743 | std::function<void()> taskFunc, |
@@ -749,7 +803,7 @@ void async_run(Coro &&coro) |
749 | 803 |
|
750 | 804 | /** |
751 | 805 | * @brief returns a function that calls a coroutine |
752 | | - * @param coro A coroutine that is awaitable |
| 806 | + * @param Coro A coroutine that is awaitable |
753 | 807 | */ |
754 | 808 | template <typename Coro> |
755 | 809 | std::function<void()> async_func(Coro &&coro) |
|
0 commit comments