From 07b790557b10d6d811ca3dcea15707449df859cc Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Fri, 19 Apr 2024 00:38:35 +0800 Subject: [PATCH] feat support Async --- src/sled/futures/future.cc | 21 +++++++++++++++++++++ src/sled/futures/future.h | 27 +++++++++++++++++++++++++-- src/sled/futures/future_test.cc | 14 ++++++++++++++ src/sled/futures/internal/promise.h | 2 +- 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/sled/futures/future.cc b/src/sled/futures/future.cc index 048c4a6..4a639e1 100644 --- a/src/sled/futures/future.cc +++ b/src/sled/futures/future.cc @@ -1,5 +1,6 @@ #include "sled/futures/future.h" +#include "sled/system/thread_pool.h" namespace sled { namespace future_detail { @@ -12,4 +13,24 @@ DecrementFuturesUsage() {} }// namespace future_detail + +static ThreadPool g_default_thread_pool; +TaskQueueBase *g_default_scheduler = &g_default_thread_pool; + +void +SetDefaultScheduler(TaskQueueBase *scheduler) noexcept +{ + if (scheduler == nullptr) { + g_default_scheduler = &g_default_thread_pool; + } else { + g_default_scheduler = scheduler; + } +} + +TaskQueueBase * +GetDefaultScheduler() noexcept +{ + return g_default_scheduler; +} + }// namespace sled diff --git a/src/sled/futures/future.h b/src/sled/futures/future.h index b2bb7b6..5bd6378 100644 --- a/src/sled/futures/future.h +++ b/src/sled/futures/future.h @@ -56,9 +56,10 @@ struct FutureData { }; }// namespace future_detail -// +void SetDefaultScheduler(TaskQueueBase *scheduler) noexcept; +TaskQueueBase *GetDefaultScheduler() noexcept; -template +template class Future { static_assert(!std::is_same::value, "Future is not allowed. Use Future instead"); static_assert(!std::is_same::value, "Future<_, void> is not allowed. Use Future<_, bool> instead"); @@ -329,6 +330,27 @@ public: return result; } + template::value>> + static Future Async(Func &&f) noexcept + { + Future result = Future::Create(); + sled::GetDefaultScheduler()->PostTask([result, f]() mutable noexcept { + try { + result.FillSuccess(f()); + } catch (const std::exception &e) { + result.FillFailure(future_detail::ExceptionFailure(e)); + } catch (...) { + result.FillFailure(future_detail::ExceptionFailure()); + } + }); + return result; + } + + static Future AsyncWithValue(const T &value) noexcept + { + return Async([value]() { return value; }); + } + static Future::type, FailureT> Successful(T &&value) noexcept { Future::type, FailureT> result @@ -437,6 +459,7 @@ private: std::shared_ptr> data_; }; + }// namespace sled #endif// SLED_FUTURES_FUTURE_H diff --git a/src/sled/futures/future_test.cc b/src/sled/futures/future_test.cc index 82b1290..5f7af21 100644 --- a/src/sled/futures/future_test.cc +++ b/src/sled/futures/future_test.cc @@ -102,4 +102,18 @@ TEST_SUITE("future") CHECK_EQ(tid, f.Result()); CHECK_NE(self_tid, f.Result()); } + + TEST_CASE("Async") + { + auto f = sled::Future::Async([]() { return 42; }); + CHECK_EQ(f.Result(), 42); + + auto f2 = sled::Future::Async([]() { + throw std::runtime_error("test"); + return 1; + }); + CHECK_FALSE(f2.IsFailed()); + auto f3 = sled::Future::AsyncWithValue("11"); + CHECK_EQ(f3.Result(), "11"); + } } diff --git a/src/sled/futures/internal/promise.h b/src/sled/futures/internal/promise.h index 8c73a62..642f727 100644 --- a/src/sled/futures/internal/promise.h +++ b/src/sled/futures/internal/promise.h @@ -10,7 +10,7 @@ namespace sled { template class Future; -template +template class Promise { static_assert(!std::is_same::value, "Promise is not allowed. Use Promise instead"); static_assert(!std::is_same::value,