Browse Source

兼容clang 8.0版本

tags/v2.9.7
tearshark 4 years ago
parent
commit
a9b2f7279e

+ 2
- 1
README.md View File

@@ -3,10 +3,11 @@
### librf - 协程库

2020-02-16 更新:

更新调度器算法,深入应用Coroutines的特性,以期获得更高调度性能。
不再支持C++14。

librf是一个基于C++ Coroutines提案 ‘Stackless Resumable Functions’编写的非对称stackless协程库。
librf是一个基于C++ Coroutines提案 ‘Stackless Resumable Functions’编写的非对称stackless协程库。

目前仅支持:


+ 10
- 9
librf/src/awaitable.h View File

@@ -19,8 +19,8 @@ namespace resumef

void set_exception(std::exception_ptr e) const
{
_state->set_exception(std::move(e));
_state = nullptr;
this->_state->set_exception(std::move(e));
this->_state = nullptr;
}

template<class _Exp>
@@ -31,7 +31,7 @@ namespace resumef

future_type get_future()
{
return future_type{ _state };
return future_type{ this->_state };
}

mutable counted_ptr<state_type> _state = make_counted<state_type>(true);
@@ -40,24 +40,25 @@ namespace resumef
template<class _Ty>
struct awaitable_t : public awaitable_impl_t<_Ty>
{
using awaitable_impl_t::awaitable_impl_t;
using typename awaitable_impl_t<_Ty>::value_type;
using awaitable_impl_t<_Ty>::awaitable_impl_t;

void set_value(value_type value) const
{
_state->set_value(std::move(value));
_state = nullptr;
this->_state->set_value(std::move(value));
this->_state = nullptr;
}
};

template<>
struct awaitable_t<void> : public awaitable_impl_t<void>
{
using awaitable_impl_t::awaitable_impl_t;
using awaitable_impl_t<void>::awaitable_impl_t;

void set_value() const
{
_state->set_value();
_state = nullptr;
this->_state->set_value();
this->_state = nullptr;
}
};
}

+ 3
- 11
librf/src/def.h View File

@@ -9,6 +9,7 @@
#include <deque>
#include <mutex>
#include <map>
#include <unordered_map>
#include <optional>
#include <assert.h>
@@ -45,13 +46,8 @@ namespace resumef
struct state_base_t;
#if _HAS_CXX17
template<class... _Mutexes>
using scoped_lock = std::scoped_lock<_Mutexes...>;
#else
template<class... _Mutexes>
using scoped_lock = std::lock_guard<_Mutexes...>;
#endif
}
#if RESUMEF_DEBUG_COUNTER
@@ -62,19 +58,15 @@ extern std::atomic<intptr_t> g_resumef_evtctx_count;
extern std::atomic<intptr_t> g_resumef_state_id;
#endif
namespace std
namespace resumef
{
#if !_HAS_CXX20
template<class T>
struct remove_cvref
{
typedef std::remove_cv_t<std::remove_reference_t<T>> type;
};
#if _HAS_CXX17
template<class T>
using remove_cvref_t = typename std::remove_cvref<T>::type;
#endif
#endif
using remove_cvref_t = typename remove_cvref<T>::type;
}
#if defined(RESUMEF_DLL_EXPORT)

+ 35
- 34
librf/src/event.h View File

@@ -26,18 +26,19 @@ namespace resumef
RF_API void reset();
//如果已经触发了awaker,则返回true
RF_API bool wait_(const event_awaker_ptr & awaker);
RF_API bool wait_(const event_awaker_ptr& awaker);
template<class callee_t, class dummy_t = std::enable_if<!std::is_same<std::remove_cv_t<callee_t>, event_awaker_ptr>::value>>
decltype(auto) wait(callee_t && awaker, dummy_t * dummy_ = nullptr)
decltype(auto) wait(callee_t&& awaker, dummy_t* dummy_ = nullptr)
{
(void)dummy_;
return wait_(std::make_shared<event_awaker>(std::forward<callee_t>(awaker)));
}
event_impl(const event_impl &) = delete;
event_impl(event_impl &&) = delete;
event_impl & operator = (const event_impl &) = delete;
event_impl & operator = (event_impl &&) = delete;
event_impl(const event_impl&) = delete;
event_impl(event_impl&&) = delete;
event_impl& operator = (const event_impl&) = delete;
event_impl& operator = (event_impl&&) = delete;
};
}
@@ -68,15 +69,15 @@ namespace resumef
RF_API future_t<bool>
wait() const;
template<class _Rep, class _Period>
template<class _Rep, class _Period>
future_t<bool>
wait_for(const std::chrono::duration<_Rep, _Period> & dt) const
wait_for(const std::chrono::duration<_Rep, _Period>& dt) const
{
return wait_for_(std::chrono::duration_cast<clock_type::duration>(dt));
}
template<class _Clock, class _Duration>
template<class _Clock, class _Duration>
future_t<bool>
wait_until(const std::chrono::time_point<_Clock, _Duration> & tp) const
wait_until(const std::chrono::time_point<_Clock, _Duration>& tp) const
{
return wait_until_(std::chrono::time_point_cast<clock_type::duration>(tp));
}
@@ -93,33 +94,33 @@ namespace resumef
}
template<class _Cont>
static future_t<intptr_t>
wait_any(const _Cont & cnt_)
wait_any(const _Cont& cnt_)
{
return wait_any_(make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
template<class _Rep, class _Period, class _Iter>
static future_t<intptr_t>
wait_any_for(const std::chrono::duration<_Rep, _Period> & dt, _Iter begin_, _Iter end_)
wait_any_for(const std::chrono::duration<_Rep, _Period>& dt, _Iter begin_, _Iter end_)
{
return wait_any_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(begin_, end_));
}
template<class _Rep, class _Period, class _Cont>
static future_t<intptr_t>
wait_any_for(const std::chrono::duration<_Rep, _Period> & dt, const _Cont & cnt_)
wait_any_for(const std::chrono::duration<_Rep, _Period>& dt, const _Cont& cnt_)
{
return wait_any_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
template<class _Clock, class _Duration, class _Iter>
template<class _Clock, class _Duration, class _Iter>
static future_t<intptr_t>
wait_any_until(const std::chrono::time_point<_Clock, _Duration> & tp, _Iter begin_, _Iter end_)
wait_any_until(const std::chrono::time_point<_Clock, _Duration>& tp, _Iter begin_, _Iter end_)
{
return wait_any_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(begin_, end_));
}
template<class _Clock, class _Duration, class _Cont>
static future_t<intptr_t>
wait_any_until(const std::chrono::time_point<_Clock, _Duration> & tp, const _Cont & cnt_)
wait_any_until(const std::chrono::time_point<_Clock, _Duration>& tp, const _Cont& cnt_)
{
return wait_any_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
@@ -136,43 +137,43 @@ namespace resumef
}
template<class _Cont>
static future_t<bool>
wait_all(const _Cont & cnt_)
wait_all(const _Cont& cnt_)
{
return wait_all(std::begin(cnt_), std::end(cnt_));
}
template<class _Rep, class _Period, class _Iter>
static future_t<bool>
wait_all_for(const std::chrono::duration<_Rep, _Period> & dt, _Iter begin_, _Iter end_)
wait_all_for(const std::chrono::duration<_Rep, _Period>& dt, _Iter begin_, _Iter end_)
{
return wait_all_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(begin_, end_));
}
template<class _Rep, class _Period, class _Cont>
static future_t<bool>
wait_all_for(const std::chrono::duration<_Rep, _Period> & dt, const _Cont & cnt_)
wait_all_for(const std::chrono::duration<_Rep, _Period>& dt, const _Cont& cnt_)
{
return wait_all_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
template<class _Clock, class _Duration, class _Iter>
static future_t<bool>
wait_all_until(const std::chrono::time_point<_Clock, _Duration> & tp, _Iter begin_, _Iter end_)
wait_all_until(const std::chrono::time_point<_Clock, _Duration>& tp, _Iter begin_, _Iter end_)
{
return wait_all_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(begin_, end_));
}
template<class _Clock, class _Duration, class _Cont>
static future_t<bool>
wait_all_until(const std::chrono::time_point<_Clock, _Duration> & tp, const _Cont & cnt_)
wait_all_until(const std::chrono::time_point<_Clock, _Duration>& tp, const _Cont& cnt_)
{
return wait_all_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
RF_API event_t(const event_t &) = default;
RF_API event_t(event_t &&) = default;
RF_API event_t & operator = (const event_t &) = default;
RF_API event_t & operator = (event_t &&) = default;
RF_API event_t(const event_t&) = default;
RF_API event_t(event_t&&) = default;
RF_API event_t& operator = (const event_t&) = default;
RF_API event_t& operator = (event_t&&) = default;
private:
template<class _Iter>
@@ -183,30 +184,30 @@ namespace resumef
for (auto i = begin_; i != end_; ++i)
evts.push_back((*i)._event);
return std::move(evts);
return evts;
}
inline future_t<bool> wait_for_(const clock_type::duration & dt) const
inline future_t<bool> wait_for_(const clock_type::duration& dt) const
{
return wait_until_(clock_type::now() + dt);
}
RF_API future_t<bool> wait_until_(const clock_type::time_point & tp) const;
RF_API future_t<bool> wait_until_(const clock_type::time_point& tp) const;
RF_API static future_t<intptr_t> wait_any_(std::vector<event_impl_ptr> && evts);
inline static future_t<intptr_t> wait_any_for_(const clock_type::duration & dt, std::vector<event_impl_ptr> && evts)
RF_API static future_t<intptr_t> wait_any_(std::vector<event_impl_ptr>&& evts);
inline static future_t<intptr_t> wait_any_for_(const clock_type::duration& dt, std::vector<event_impl_ptr>&& evts)
{
return wait_any_until_(clock_type::now() + dt, std::forward<std::vector<event_impl_ptr>>(evts));
}
RF_API static future_t<intptr_t> wait_any_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts);
RF_API static future_t<intptr_t> wait_any_until_(const clock_type::time_point& tp, std::vector<event_impl_ptr>&& evts);
RF_API static future_t<bool> wait_all_(std::vector<event_impl_ptr> && evts);
inline static future_t<bool> wait_all_for_(const clock_type::duration & dt, std::vector<event_impl_ptr> && evts)
RF_API static future_t<bool> wait_all_(std::vector<event_impl_ptr>&& evts);
inline static future_t<bool> wait_all_for_(const clock_type::duration& dt, std::vector<event_impl_ptr>&& evts)
{
return wait_all_until_(clock_type::now() + dt, std::forward<std::vector<event_impl_ptr>>(evts));
}
RF_API static future_t<bool> wait_all_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts);
RF_API static future_t<bool> wait_all_until_(const clock_type::time_point& tp, std::vector<event_impl_ptr>&& evts);
};
}

+ 8
- 8
librf/src/exception.inl View File

@@ -16,41 +16,41 @@ namespace resumef

const char* get_error_string(error_code fe, const char* classname);

struct future_exception : std::exception
struct future_exception : std::logic_error
{
error_code _error;
future_exception(error_code fe)
: exception(get_error_string(fe, "future_exception"))
: logic_error(get_error_string(fe, "future_exception"))
, _error(fe)
{
}
};

struct lock_exception : std::exception
struct lock_exception : std::logic_error
{
error_code _error;
lock_exception(error_code fe)
: exception(get_error_string(fe, "lock_exception"))
: logic_error(get_error_string(fe, "lock_exception"))
, _error(fe)
{
}
};

struct channel_exception : std::exception
struct channel_exception : std::logic_error
{
error_code _error;
channel_exception(error_code fe)
: exception(get_error_string(fe, "channel_exception"))
: logic_error(get_error_string(fe, "channel_exception"))
, _error(fe)
{
}
};

struct timer_canceled_exception : public std::exception
struct timer_canceled_exception : public std::logic_error
{
error_code _error;
timer_canceled_exception(error_code fe)
: exception(get_error_string(fe, "timer canceled"))
: logic_error(get_error_string(fe, "timer canceled"))
, _error(fe)
{
}

+ 162
- 171
librf/src/generator.h View File

@@ -14,234 +14,225 @@
#define _EXPERIMENTAL_GENERATOR_
#ifndef RC_INVOKED
#ifndef _RESUMABLE_FUNCTIONS_SUPPORTED
#error <experimental/generator> requires /await compiler option
#endif /* _RESUMABLE_FUNCTIONS_SUPPORTED */
#include <experimental/resumable>
#include <experimental/coroutine>
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,_STL_WARNING_LEVEL)
#pragma warning(disable: _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
_STD_BEGIN
namespace experimental {
template <typename _Ty, typename promise_type>
struct generator_iterator;
template<typename promise_type>
struct generator_iterator<void, promise_type>
{
typedef _STD input_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
coroutine_handle<promise_type> _Coro;
generator_iterator(nullptr_t) : _Coro(nullptr)
{
}
generator_iterator(coroutine_handle<promise_type> _CoroArg) : _Coro(_CoroArg)
{
}
generator_iterator &operator++()
{
_Coro.resume();
if (_Coro.done())
_Coro = nullptr;
return *this;
}
namespace std {
namespace experimental {
void operator++(int)
{
// This postincrement operator meets the requirements of the Ranges TS
// InputIterator concept, but not those of Standard C++ InputIterator.
++* this;
}
template <typename _Ty, typename promise_type>
struct generator_iterator;
bool operator==(generator_iterator const &right_) const
template<typename promise_type>
struct generator_iterator<void, promise_type>
{
return _Coro == right_._Coro;
}
typedef std::input_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
bool operator!=(generator_iterator const &right_) const
{
return !(*this == right_);
}
};
template <typename promise_type>
struct generator_iterator<nullptr_t, promise_type> : public generator_iterator<void, promise_type>
{
generator_iterator(nullptr_t) : generator_iterator<void, promise_type>(nullptr)
{
}
generator_iterator(coroutine_handle<promise_type> _CoroArg) : generator_iterator<void, promise_type>(_CoroArg)
{
}
};
coroutine_handle<promise_type> _Coro;
template <typename _Ty, typename promise_type>
struct generator_iterator : public generator_iterator<void, promise_type>
{
using value_type = _Ty;
using reference = _Ty const&;
using pointer = _Ty const*;
generator_iterator(nullptr_t) : generator_iterator<void, promise_type>(nullptr)
{
}
generator_iterator(coroutine_handle<promise_type> _CoroArg) : generator_iterator<void, promise_type>(_CoroArg)
{
}
reference operator*() const
{
return *_Coro.promise()._CurrentValue;
}
generator_iterator(nullptr_t) : _Coro(nullptr)
{
}
pointer operator->() const
{
return _Coro.promise()._CurrentValue;
}
};
template <typename _Ty, typename _Alloc = allocator<char>>
struct generator
{
struct promise_type
{
_Ty const *_CurrentValue;
generator_iterator(coroutine_handle<promise_type> _CoroArg) : _Coro(_CoroArg)
{
}
promise_type &get_return_object()
generator_iterator& operator++()
{
_Coro.resume();
if (_Coro.done())
_Coro = nullptr;
return *this;
}
bool initial_suspend()
void operator++(int)
{
return (true);
// This postincrement operator meets the requirements of the Ranges TS
// InputIterator concept, but not those of Standard C++ InputIterator.
++* this;
}
bool final_suspend()
bool operator==(generator_iterator const& right_) const
{
return (true);
return _Coro == right_._Coro;
}
void yield_value(_Ty const &_Value)
bool operator!=(generator_iterator const& right_) const
{
_CurrentValue = _STD addressof(_Value);
return !(*this == right_);
}
};
template<class = _STD enable_if_t<!is_same_v<_Ty, void>, _Ty>>
void return_value(_Ty const &_Value)
template <typename promise_type>
struct generator_iterator<nullptr_t, promise_type> : public generator_iterator<void, promise_type>
{
generator_iterator(nullptr_t) : generator_iterator<void, promise_type>(nullptr)
{
_CurrentValue = _STD addressof(_Value);
}
template<class = _STD enable_if_t<is_same_v<_Ty, void>, _Ty>>
void return_value()
generator_iterator(coroutine_handle<promise_type> _CoroArg) : generator_iterator<void, promise_type>(_CoroArg)
{
_CurrentValue = nullptr;
}
};
template <typename _Ty, typename promise_type>
struct generator_iterator : public generator_iterator<void, promise_type>
{
using value_type = _Ty;
using reference = _Ty const&;
using pointer = _Ty const*;
template <typename _Uty>
_Uty && await_transform(_Uty &&_Whatever)
generator_iterator(nullptr_t) : generator_iterator<void, promise_type>(nullptr)
{
}
generator_iterator(coroutine_handle<promise_type> _CoroArg) : generator_iterator<void, promise_type>(_CoroArg)
{
static_assert(_Always_false<_Uty>::value,
"co_await is not supported in coroutines of type std::experiemental::generator");
return _STD forward<_Uty>(_Whatever);
}
using _Alloc_char = _Rebind_alloc_t<_Alloc, char>;
static_assert(is_same_v<char*, typename allocator_traits<_Alloc_char>::pointer>,
"generator does not support allocators with fancy pointer types");
static_assert(allocator_traits<_Alloc_char>::is_always_equal::value,
"generator only supports stateless allocators");
void *operator new(size_t _Size)
reference operator*() const
{
_Alloc_char _Al;
return _Al.allocate(_Size);
return *this->_Coro.promise()._CurrentValue;
}
void operator delete(void *_Ptr, size_t _Size)
pointer operator->() const
{
_Alloc_char _Al;
return _Al.deallocate(static_cast<char *>(_Ptr), _Size);
return this->_Coro.promise()._CurrentValue;
}
};
typedef generator_iterator<_Ty, promise_type> iterator;
iterator begin()
template <typename _Ty, typename _Alloc = allocator<char>>
struct generator
{
if (_Coro)
struct promise_type
{
_Coro.resume();
if (_Coro.done())
return{ nullptr };
_Ty const* _CurrentValue;
promise_type& get_return_object()
{
return *this;
}
bool initial_suspend()
{
return (true);
}
bool final_suspend()
{
return (true);
}
void yield_value(_Ty const& _Value)
{
_CurrentValue = std::addressof(_Value);
}
template<class = std::enable_if_t<!std::is_same_v<_Ty, void>, _Ty>>
void return_value(_Ty const& _Value)
{
_CurrentValue = std::addressof(_Value);
}
template<class = std::enable_if_t<std::is_same_v<_Ty, void>, _Ty>>
void return_value()
{
_CurrentValue = nullptr;
}
template <typename _Uty>
_Uty&& await_transform(_Uty&& _Whatever)
{
static_assert(std::is_same_v<_Uty, void>,
"co_await is not supported in coroutines of type std::experiemental::generator");
return std::forward<_Uty>(_Whatever);
}
using _Alloc_char = typename allocator_traits<_Alloc>::template rebind_alloc<char>;
static_assert(std::is_same_v<char*, typename std::allocator_traits<_Alloc_char>::pointer>,
"generator does not support allocators with fancy pointer types");
static_assert(std::allocator_traits<_Alloc_char>::is_always_equal::value,
"generator only supports stateless allocators");
void* operator new(size_t _Size)
{
_Alloc_char _Al;
return _Al.allocate(_Size);
}
void operator delete(void* _Ptr, size_t _Size)
{
_Alloc_char _Al;
return _Al.deallocate(static_cast<char*>(_Ptr), _Size);
}
};
typedef generator_iterator<_Ty, promise_type> iterator;
iterator begin()
{
if (_Coro)
{
_Coro.resume();
if (_Coro.done())
return{ nullptr };
}
return { _Coro };
}
return { _Coro };
}
iterator end()
{
return{ nullptr };
}
explicit generator(promise_type &_Prom)
: _Coro(coroutine_handle<promise_type>::from_promise(_Prom))
{
}
iterator end()
{
return{ nullptr };
}
generator() = default;
explicit generator(promise_type& _Prom)
: _Coro(coroutine_handle<promise_type>::from_promise(_Prom))
{
}
generator(generator const &) = delete;
generator() = default;
generator &operator=(generator const &) = delete;
generator(generator const&) = delete;
generator(generator &&right_) noexcept
: _Coro(right_._Coro)
{
right_._Coro = nullptr;
}
generator& operator=(generator const&) = delete;
generator &operator=(generator &&right_) noexcept
{
if (this != _STD addressof(right_)) {
_Coro = right_._Coro;
generator(generator&& right_) noexcept
: _Coro(right_._Coro)
{
right_._Coro = nullptr;
}
return *this;
}
~generator()
{
if (_Coro) {
_Coro.destroy();
generator& operator=(generator&& right_) noexcept
{
if (this != std::addressof(right_)) {
_Coro = right_._Coro;
right_._Coro = nullptr;
}
return *this;
}
}
coroutine_handle<promise_type> detach()
{
auto t = _Coro;
_Coro = nullptr;
return t;
}
~generator()
{
if (_Coro) {
_Coro.destroy();
}
}
private:
coroutine_handle<promise_type> _Coro = nullptr;
};
coroutine_handle<promise_type> detach()
{
auto t = _Coro;
_Coro = nullptr;
return t;
}
} // namespace experimental
private:
coroutine_handle<promise_type> _Coro = nullptr;
};
_STD_END
} // namespace experimental
} // namespace std
#pragma pop_macro("new")
#pragma pack(pop)

+ 20
- 19
librf/src/mutex.h View File

@@ -23,21 +23,22 @@ namespace resumef
RF_API mutex_impl();
//如果已经触发了awaker,则返回true
RF_API bool lock_(const mutex_awaker_ptr & awaker);
RF_API bool try_lock_(const mutex_awaker_ptr & awaker);
RF_API bool lock_(const mutex_awaker_ptr& awaker);
RF_API bool try_lock_(const mutex_awaker_ptr& awaker);
RF_API void unlock();
template<class callee_t, class dummy_t = std::enable_if<!std::is_same<std::remove_cv_t<callee_t>, mutex_awaker_ptr>::value>>
decltype(auto) lock(callee_t && awaker, dummy_t * dummy_ = nullptr)
decltype(auto) lock(callee_t&& awaker, dummy_t* dummy_ = nullptr)
{
(void)dummy_;
return lock_(std::make_shared<mutex_awaker>(std::forward<callee_t>(awaker)));
}
private:
mutex_impl(const mutex_impl &) = delete;
mutex_impl(mutex_impl &&) = delete;
mutex_impl & operator = (const mutex_impl &) = delete;
mutex_impl & operator = (mutex_impl &&) = delete;
mutex_impl(const mutex_impl&) = delete;
mutex_impl(mutex_impl&&) = delete;
mutex_impl& operator = (const mutex_impl&) = delete;
mutex_impl& operator = (mutex_impl&&) = delete;
};
}
@@ -62,32 +63,32 @@ namespace resumef
RF_API bool
try_lock() const;
/*
template<class _Rep, class _Period>
awaitable_t<bool>
/*
template<class _Rep, class _Period>
awaitable_t<bool>
try_lock_for(const std::chrono::duration<_Rep, _Period> & dt) const
{
return try_lock_for_(std::chrono::duration_cast<clock_type::duration>(dt));
}
template<class _Clock, class _Duration>
awaitable_t<bool>
template<class _Clock, class _Duration>
awaitable_t<bool>
try_lock_until(const std::chrono::time_point<_Clock, _Duration> & tp) const
{
return try_lock_until_(std::chrono::time_point_cast<clock_type::duration>(tp));
}
*/
*/
RF_API mutex_t(const mutex_t &) = default;
RF_API mutex_t(mutex_t &&) = default;
RF_API mutex_t & operator = (const mutex_t &) = default;
RF_API mutex_t & operator = (mutex_t &&) = default;
RF_API mutex_t(const mutex_t&) = default;
RF_API mutex_t(mutex_t&&) = default;
RF_API mutex_t& operator = (const mutex_t&) = default;
RF_API mutex_t& operator = (mutex_t&&) = default;
private:
inline future_t<bool> try_lock_for_(const clock_type::duration & dt) const
inline future_t<bool> try_lock_for_(const clock_type::duration& dt) const
{
return try_lock_until_(clock_type::now() + dt);
}
RF_API future_t<bool> try_lock_until_(const clock_type::time_point & tp) const;
RF_API future_t<bool> try_lock_until_(const clock_type::time_point& tp) const;
};
#if _HAS_CXX17

+ 3
- 2
librf/src/promise.h View File

@@ -21,7 +21,7 @@ namespace resumef
promise_impl_t(promise_impl_t&& _Right) noexcept = default;
promise_impl_t& operator = (promise_impl_t&& _Right) noexcept = default;
promise_impl_t(const promise_impl_t&) = delete;
promise_impl_t & operator = (const promise_impl_t&) = delete;
promise_impl_t& operator = (const promise_impl_t&) = delete;

suspend_on_initial initial_suspend() noexcept;
suspend_on_final final_suspend() noexcept;
@@ -29,10 +29,11 @@ namespace resumef
future_type get_return_object();
void cancellation_requested();
};
template<class _Ty>
struct promise_t : public promise_impl_t<_Ty>
{
using typename promise_impl_t<_Ty>::value_type;
using promise_impl_t<_Ty>::_state;

void return_value(value_type val);

+ 2
- 2
librf/src/rf_task.h View File

@@ -34,7 +34,7 @@ namespace resumef
using state_type = state_t<value_type>;
task_t() = default;
task_t(future_type && f)
task_t(future_type&& f)
{
initialize(std::forward<future_type>(f));
}
@@ -70,7 +70,7 @@ namespace resumef
//这个'函数对象'被调用后,返回generator<_Ty>/future_t<_Ty>类型
//然后'函数对象'作为异步执行的上下文状态保存起来
template<class _Ctx>
struct ctx_task_t : public task_t<typename std::remove_cvref<decltype(std::declval<_Ctx>()())>::type>
struct ctx_task_t : public task_t<remove_cvref_t<decltype(std::declval<_Ctx>()())>>
{
using context_type = _Ctx;

+ 11
- 11
librf/src/scheduler.h View File

@@ -30,7 +30,7 @@ namespace resumef
timer_mgr_ptr _timer;
RF_API void new_task(task_base_t * task);
RF_API void new_task(task_base_t* task);
//void cancel_all_task_();
public:
@@ -39,10 +39,10 @@ namespace resumef
RF_API void run();
//RF_API void break_all();
template<class _Ty, typename = std::enable_if_t<std::is_callable_v<_Ty> || is_future_v<_Ty> || is_generator_v<_Ty> >>
inline void operator + (_Ty && t_)
template<class _Ty, typename = std::enable_if_t<std::is_callable<_Ty>::value || is_future_v<_Ty> || is_generator_v<_Ty> >>
inline void operator + (_Ty&& t_)
{
if constexpr(std::is_callable_v<_Ty>)
if constexpr (std::is_callable<_Ty>::value)
new_task(new ctx_task_t<_Ty>(std::forward<_Ty>(t_)));
else
new_task(new task_t<_Ty>(std::forward<_Ty>(t_)));
@@ -54,7 +54,7 @@ namespace resumef
return _ready_task.empty() && _runing_states.empty() && _timer->empty();
}
inline timer_manager * timer() const
inline timer_manager* timer() const
{
return _timer.get();
}
@@ -85,16 +85,16 @@ namespace resumef
RF_API local_scheduler();
RF_API ~local_scheduler();
local_scheduler(local_scheduler && right_) = delete;
local_scheduler & operator = (local_scheduler && right_) = delete;
local_scheduler(const local_scheduler &) = delete;
local_scheduler & operator = (const local_scheduler &) = delete;
local_scheduler(local_scheduler&& right_) = delete;
local_scheduler& operator = (local_scheduler&& right_) = delete;
local_scheduler(const local_scheduler&) = delete;
local_scheduler& operator = (const local_scheduler&) = delete;
#if RESUMEF_ENABLE_MULT_SCHEDULER
private:
scheduler_t* _scheduler_ptr;
#endif
};
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
#if !RESUMEF_ENABLE_MULT_SCHEDULER
//获得当前线程下的调度器
inline scheduler_t* this_scheduler()
@@ -108,5 +108,5 @@ namespace resumef
#define GO (*::resumef::this_scheduler()) + [=]()mutable->resumef::future_t<>
#endif
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
}

+ 1
- 1
librf/src/sleep.h View File

@@ -12,7 +12,7 @@ namespace resumef
inline future_t<> sleep_for_(const std::chrono::system_clock::duration& dt_, scheduler_t& scheduler_)
{
return std::move(sleep_until_(std::chrono::system_clock::now() + dt_, scheduler_));
return sleep_until_(std::chrono::system_clock::now() + dt_, scheduler_);
}
template<class _Rep, class _Period>

+ 3
- 3
librf/src/type_traits.inl View File

@@ -7,19 +7,19 @@ namespace resumef
template<class _Ty>
struct is_promise<promise_t<_Ty>> : std::true_type {};
template<class _Ty>
_INLINE_VAR constexpr bool is_promise_v = is_promise<std::remove_cvref_t<_Ty>>::value;
constexpr bool is_promise_v = is_promise<remove_cvref_t<_Ty>>::value;

template<class _PromiseT>
struct is_future : std::false_type {};
template<class _Ty>
struct is_future<future_t<_Ty>> : std::true_type {};
template<class _Ty>
_INLINE_VAR constexpr bool is_future_v = is_future<std::remove_cvref_t<_Ty>>::value;
constexpr bool is_future_v = is_future<remove_cvref_t<_Ty>>::value;

template<class _G>
struct is_generator : std::false_type {};
template <typename _Ty, typename _Alloc>
struct is_generator<generator_t<_Ty, _Alloc>> : std::true_type {};
template<class _Ty>
_INLINE_VAR constexpr bool is_generator_v = is_generator<std::remove_cvref_t<_Ty>>::value;
constexpr bool is_generator_v = is_generator<remove_cvref_t<_Ty>>::value;
}

+ 2
- 2
tutorial/test_async_modern_cb.cpp View File

@@ -82,7 +82,7 @@ __declspec(noinline)
auto tostring_async(_Input_t&& value, _Callable_t&& token)
{
//适配器类型
using _Adapter_t = modern_callback_adapter_t<typename std::remove_cvref<_Callable_t>::type, void(std::string)>;
using _Adapter_t = modern_callback_adapter_t<typename resumef::remove_cvref_t<_Callable_t>, void(std::string)>;
//通过适配器获得兼容_Signature_t类型的真正的回调,以及返回值_Return_t
auto adapter = typename _Adapter_t::traits(std::forward<_Callable_t>(token));

@@ -100,7 +100,7 @@ auto tostring_async(_Input_t&& value, _Callable_t&& token)

//或者宏版本写法
#define MODERN_CALLBACK_TRAITS(_Token_value, _Signature_t) \
using _Adapter_t = modern_callback_adapter_t<typename std::remove_cvref<_Callable_t>::type, _Signature_t>; \
using _Adapter_t = modern_callback_adapter_t<typename resumef::remove_cvref_t<_Callable_t>, _Signature_t>; \
auto _Adapter_value = typename _Adapter_t::traits(std::forward<_Callable_t>(_Token_value))
#define MODERN_CALLBACK_CALL() std::move(std::get<0>(_Adapter_value))
#define MODERN_CALLBACK_RETURN() return std::move(std::get<1>(_Adapter_value)).get()

Loading…
Cancel
Save