feat support Async
This commit is contained in:
parent
5d07e41460
commit
07b790557b
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include "sled/futures/future.h"
|
#include "sled/futures/future.h"
|
||||||
|
#include "sled/system/thread_pool.h"
|
||||||
|
|
||||||
namespace sled {
|
namespace sled {
|
||||||
namespace future_detail {
|
namespace future_detail {
|
||||||
@ -12,4 +13,24 @@ DecrementFuturesUsage()
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
}// namespace future_detail
|
}// 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
|
}// namespace sled
|
||||||
|
@ -56,9 +56,10 @@ struct FutureData {
|
|||||||
};
|
};
|
||||||
}// namespace future_detail
|
}// namespace future_detail
|
||||||
|
|
||||||
//
|
void SetDefaultScheduler(TaskQueueBase *scheduler) noexcept;
|
||||||
|
TaskQueueBase *GetDefaultScheduler() noexcept;
|
||||||
|
|
||||||
template<typename T, typename FailureT>
|
template<typename T, typename FailureT = std::exception>
|
||||||
class Future {
|
class Future {
|
||||||
static_assert(!std::is_same<T, void>::value, "Future<void, _> is not allowed. Use Future<bool, _> instead");
|
static_assert(!std::is_same<T, void>::value, "Future<void, _> is not allowed. Use Future<bool, _> instead");
|
||||||
static_assert(!std::is_same<FailureT, void>::value, "Future<_, void> is not allowed. Use Future<_, bool> instead");
|
static_assert(!std::is_same<FailureT, void>::value, "Future<_, void> is not allowed. Use Future<_, bool> instead");
|
||||||
@ -329,6 +330,27 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Func, typename = future_detail::enable_if_t<future_detail::is_invocable<Func>::value>>
|
||||||
|
static Future<T, FailureT> Async(Func &&f) noexcept
|
||||||
|
{
|
||||||
|
Future<T, FailureT> result = Future<T, FailureT>::Create();
|
||||||
|
sled::GetDefaultScheduler()->PostTask([result, f]() mutable noexcept {
|
||||||
|
try {
|
||||||
|
result.FillSuccess(f());
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
result.FillFailure(future_detail::ExceptionFailure<FailureT>(e));
|
||||||
|
} catch (...) {
|
||||||
|
result.FillFailure(future_detail::ExceptionFailure<FailureT>());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<T, FailureT> AsyncWithValue(const T &value) noexcept
|
||||||
|
{
|
||||||
|
return Async([value]() { return value; });
|
||||||
|
}
|
||||||
|
|
||||||
static Future<typename std::decay<T>::type, FailureT> Successful(T &&value) noexcept
|
static Future<typename std::decay<T>::type, FailureT> Successful(T &&value) noexcept
|
||||||
{
|
{
|
||||||
Future<typename std::decay<T>::type, FailureT> result
|
Future<typename std::decay<T>::type, FailureT> result
|
||||||
@ -437,6 +459,7 @@ private:
|
|||||||
|
|
||||||
std::shared_ptr<future_detail::FutureData<T, FailureT>> data_;
|
std::shared_ptr<future_detail::FutureData<T, FailureT>> data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace sled
|
}// namespace sled
|
||||||
|
|
||||||
#endif// SLED_FUTURES_FUTURE_H
|
#endif// SLED_FUTURES_FUTURE_H
|
||||||
|
@ -102,4 +102,18 @@ TEST_SUITE("future")
|
|||||||
CHECK_EQ(tid, f.Result());
|
CHECK_EQ(tid, f.Result());
|
||||||
CHECK_NE(self_tid, f.Result());
|
CHECK_NE(self_tid, f.Result());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Async")
|
||||||
|
{
|
||||||
|
auto f = sled::Future<int>::Async([]() { return 42; });
|
||||||
|
CHECK_EQ(f.Result(), 42);
|
||||||
|
|
||||||
|
auto f2 = sled::Future<int>::Async([]() {
|
||||||
|
throw std::runtime_error("test");
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
CHECK_FALSE(f2.IsFailed());
|
||||||
|
auto f3 = sled::Future<std::string>::AsyncWithValue("11");
|
||||||
|
CHECK_EQ(f3.Result(), "11");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ namespace sled {
|
|||||||
template<typename T, typename FailureT>
|
template<typename T, typename FailureT>
|
||||||
class Future;
|
class Future;
|
||||||
|
|
||||||
template<typename T, typename FailureT>
|
template<typename T, typename FailureT = std::exception>
|
||||||
class Promise {
|
class Promise {
|
||||||
static_assert(!std::is_same<T, void>::value, "Promise<void, _> is not allowed. Use Promise<bool, _> instead");
|
static_assert(!std::is_same<T, void>::value, "Promise<void, _> is not allowed. Use Promise<bool, _> instead");
|
||||||
static_assert(!std::is_same<FailureT, void>::value,
|
static_assert(!std::is_same<FailureT, void>::value,
|
||||||
|
Loading…
Reference in New Issue
Block a user