Commit 07b79055 authored by tqcq's avatar tqcq
Browse files

feat support Async

parent 5d07e414
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line

#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
+25 −2
Original line number Diff line number Diff line
@@ -56,9 +56,10 @@ struct FutureData {
};
}// 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 {
    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");
@@ -329,6 +330,27 @@ public:
        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
    {
        Future<typename std::decay<T>::type, FailureT> result
@@ -437,6 +459,7 @@ private:

    std::shared_ptr<future_detail::FutureData<T, FailureT>> data_;
};

}// namespace sled

#endif// SLED_FUTURES_FUTURE_H
+14 −0
Original line number Diff line number Diff line
@@ -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<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");
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ namespace sled {
template<typename T, typename FailureT>
class Future;

template<typename T, typename FailureT>
template<typename T, typename FailureT = std::exception>
class Promise {
    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,