Procházet zdrojové kódy

兼容clang 8.0版本

tags/v2.9.7
tearshark před 4 roky
rodič
revize
a9b2f7279e

+ 2
- 1
README.md Zobrazit soubor

### librf - 协程库 ### librf - 协程库


2020-02-16 更新: 2020-02-16 更新:

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


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


目前仅支持: 目前仅支持:



+ 10
- 9
librf/src/awaitable.h Zobrazit soubor



void set_exception(std::exception_ptr e) const 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> template<class _Exp>


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


mutable counted_ptr<state_type> _state = make_counted<state_type>(true); mutable counted_ptr<state_type> _state = make_counted<state_type>(true);
template<class _Ty> template<class _Ty>
struct awaitable_t : public awaitable_impl_t<_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 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<> template<>
struct awaitable_t<void> : public awaitable_impl_t<void> 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 void set_value() const
{ {
_state->set_value();
_state = nullptr;
this->_state->set_value();
this->_state = nullptr;
} }
}; };
} }

+ 3
- 11
librf/src/def.h Zobrazit soubor

#include <deque> #include <deque>
#include <mutex> #include <mutex>
#include <map> #include <map>
#include <unordered_map>
#include <optional> #include <optional>
#include <assert.h> #include <assert.h>
struct state_base_t; struct state_base_t;
#if _HAS_CXX17
template<class... _Mutexes> template<class... _Mutexes>
using scoped_lock = std::scoped_lock<_Mutexes...>; using scoped_lock = std::scoped_lock<_Mutexes...>;
#else
template<class... _Mutexes>
using scoped_lock = std::lock_guard<_Mutexes...>;
#endif
} }
#if RESUMEF_DEBUG_COUNTER #if RESUMEF_DEBUG_COUNTER
extern std::atomic<intptr_t> g_resumef_state_id; extern std::atomic<intptr_t> g_resumef_state_id;
#endif #endif
namespace std
namespace resumef
{ {
#if !_HAS_CXX20
template<class T> template<class T>
struct remove_cvref struct remove_cvref
{ {
typedef std::remove_cv_t<std::remove_reference_t<T>> type; typedef std::remove_cv_t<std::remove_reference_t<T>> type;
}; };
#if _HAS_CXX17
template<class T> 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) #if defined(RESUMEF_DLL_EXPORT)

+ 35
- 34
librf/src/event.h Zobrazit soubor

RF_API void reset(); RF_API void reset();
//如果已经触发了awaker,则返回true //如果已经触发了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>> 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))); 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;
}; };
} }
RF_API future_t<bool> RF_API future_t<bool>
wait() const; wait() const;
template<class _Rep, class _Period>
template<class _Rep, class _Period>
future_t<bool> 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)); return wait_for_(std::chrono::duration_cast<clock_type::duration>(dt));
} }
template<class _Clock, class _Duration>
template<class _Clock, class _Duration>
future_t<bool> 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)); return wait_until_(std::chrono::time_point_cast<clock_type::duration>(tp));
} }
} }
template<class _Cont> template<class _Cont>
static future_t<intptr_t> 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_))); return wait_any_(make_event_vector(std::begin(cnt_), std::end(cnt_)));
} }
template<class _Rep, class _Period, class _Iter> template<class _Rep, class _Period, class _Iter>
static future_t<intptr_t> 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_)); return wait_any_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(begin_, end_));
} }
template<class _Rep, class _Period, class _Cont> template<class _Rep, class _Period, class _Cont>
static future_t<intptr_t> 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_))); 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> 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_)); 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> template<class _Clock, class _Duration, class _Cont>
static future_t<intptr_t> 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_))); return wait_any_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(std::begin(cnt_), std::end(cnt_)));
} }
} }
template<class _Cont> template<class _Cont>
static future_t<bool> static future_t<bool>
wait_all(const _Cont & cnt_)
wait_all(const _Cont& cnt_)
{ {
return wait_all(std::begin(cnt_), std::end(cnt_)); return wait_all(std::begin(cnt_), std::end(cnt_));
} }
template<class _Rep, class _Period, class _Iter> template<class _Rep, class _Period, class _Iter>
static future_t<bool> 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_)); return wait_all_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(begin_, end_));
} }
template<class _Rep, class _Period, class _Cont> template<class _Rep, class _Period, class _Cont>
static future_t<bool> 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_))); 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> template<class _Clock, class _Duration, class _Iter>
static future_t<bool> 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_)); 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> template<class _Clock, class _Duration, class _Cont>
static future_t<bool> 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_))); 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: private:
template<class _Iter> template<class _Iter>
for (auto i = begin_; i != end_; ++i) for (auto i = begin_; i != end_; ++i)
evts.push_back((*i)._event); 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); 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)); 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)); 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 Zobrazit soubor



const char* get_error_string(error_code fe, const char* classname); 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; error_code _error;
future_exception(error_code fe) future_exception(error_code fe)
: exception(get_error_string(fe, "future_exception"))
: logic_error(get_error_string(fe, "future_exception"))
, _error(fe) , _error(fe)
{ {
} }
}; };


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


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


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

+ 162
- 171
librf/src/generator.h Zobrazit soubor

#define _EXPERIMENTAL_GENERATOR_ #define _EXPERIMENTAL_GENERATOR_
#ifndef RC_INVOKED #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 pack(push,_CRT_PACKING)
#pragma warning(push,_STL_WARNING_LEVEL)
#pragma warning(disable: _STL_DISABLED_WARNINGS)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new") #pragma push_macro("new")
#undef 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; 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; 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 pop_macro("new")
#pragma pack(pop) #pragma pack(pop)

+ 20
- 19
librf/src/mutex.h Zobrazit soubor

RF_API mutex_impl(); RF_API mutex_impl();
//如果已经触发了awaker,则返回true //如果已经触发了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(); 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>> 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))); return lock_(std::make_shared<mutex_awaker>(std::forward<callee_t>(awaker)));
} }
private: 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;
}; };
} }
RF_API bool RF_API bool
try_lock() const; 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 try_lock_for(const std::chrono::duration<_Rep, _Period> & dt) const
{ {
return try_lock_for_(std::chrono::duration_cast<clock_type::duration>(dt)); 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 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)); 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: 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); 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 #if _HAS_CXX17

+ 3
- 2
librf/src/promise.h Zobrazit soubor

promise_impl_t(promise_impl_t&& _Right) noexcept = default; promise_impl_t(promise_impl_t&& _Right) noexcept = default;
promise_impl_t& operator = (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(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_initial initial_suspend() noexcept;
suspend_on_final final_suspend() noexcept; suspend_on_final final_suspend() noexcept;
future_type get_return_object(); future_type get_return_object();
void cancellation_requested(); void cancellation_requested();
}; };
template<class _Ty> template<class _Ty>
struct promise_t : public promise_impl_t<_Ty> struct promise_t : public promise_impl_t<_Ty>
{ {
using typename promise_impl_t<_Ty>::value_type;
using promise_impl_t<_Ty>::_state; using promise_impl_t<_Ty>::_state;


void return_value(value_type val); void return_value(value_type val);

+ 2
- 2
librf/src/rf_task.h Zobrazit soubor

using state_type = state_t<value_type>; using state_type = state_t<value_type>;
task_t() = default; task_t() = default;
task_t(future_type && f)
task_t(future_type&& f)
{ {
initialize(std::forward<future_type>(f)); initialize(std::forward<future_type>(f));
} }
//这个'函数对象'被调用后,返回generator<_Ty>/future_t<_Ty>类型 //这个'函数对象'被调用后,返回generator<_Ty>/future_t<_Ty>类型
//然后'函数对象'作为异步执行的上下文状态保存起来 //然后'函数对象'作为异步执行的上下文状态保存起来
template<class _Ctx> 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; using context_type = _Ctx;

+ 11
- 11
librf/src/scheduler.h Zobrazit soubor

timer_mgr_ptr _timer; 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_(); //void cancel_all_task_();
public: public:
RF_API void run(); RF_API void run();
//RF_API void break_all(); //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_))); new_task(new ctx_task_t<_Ty>(std::forward<_Ty>(t_)));
else else
new_task(new task_t<_Ty>(std::forward<_Ty>(t_))); new_task(new task_t<_Ty>(std::forward<_Ty>(t_)));
return _ready_task.empty() && _runing_states.empty() && _timer->empty(); return _ready_task.empty() && _runing_states.empty() && _timer->empty();
} }
inline timer_manager * timer() const
inline timer_manager* timer() const
{ {
return _timer.get(); return _timer.get();
} }
RF_API local_scheduler(); RF_API local_scheduler();
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 #if RESUMEF_ENABLE_MULT_SCHEDULER
private: private:
scheduler_t* _scheduler_ptr; scheduler_t* _scheduler_ptr;
#endif #endif
}; };
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
#if !RESUMEF_ENABLE_MULT_SCHEDULER #if !RESUMEF_ENABLE_MULT_SCHEDULER
//获得当前线程下的调度器 //获得当前线程下的调度器
inline scheduler_t* this_scheduler() inline scheduler_t* this_scheduler()
#define GO (*::resumef::this_scheduler()) + [=]()mutable->resumef::future_t<> #define GO (*::resumef::this_scheduler()) + [=]()mutable->resumef::future_t<>
#endif #endif
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
} }

+ 1
- 1
librf/src/sleep.h Zobrazit soubor

inline future_t<> sleep_for_(const std::chrono::system_clock::duration& dt_, scheduler_t& scheduler_) 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> template<class _Rep, class _Period>

+ 3
- 3
librf/src/type_traits.inl Zobrazit soubor

template<class _Ty> template<class _Ty>
struct is_promise<promise_t<_Ty>> : std::true_type {}; struct is_promise<promise_t<_Ty>> : std::true_type {};
template<class _Ty> 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> template<class _PromiseT>
struct is_future : std::false_type {}; struct is_future : std::false_type {};
template<class _Ty> template<class _Ty>
struct is_future<future_t<_Ty>> : std::true_type {}; struct is_future<future_t<_Ty>> : std::true_type {};
template<class _Ty> 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> template<class _G>
struct is_generator : std::false_type {}; struct is_generator : std::false_type {};
template <typename _Ty, typename _Alloc> template <typename _Ty, typename _Alloc>
struct is_generator<generator_t<_Ty, _Alloc>> : std::true_type {}; struct is_generator<generator_t<_Ty, _Alloc>> : std::true_type {};
template<class _Ty> 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 Zobrazit soubor

auto tostring_async(_Input_t&& value, _Callable_t&& token) 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 //通过适配器获得兼容_Signature_t类型的真正的回调,以及返回值_Return_t
auto adapter = typename _Adapter_t::traits(std::forward<_Callable_t>(token)); auto adapter = typename _Adapter_t::traits(std::forward<_Callable_t>(token));




//或者宏版本写法 //或者宏版本写法
#define MODERN_CALLBACK_TRAITS(_Token_value, _Signature_t) \ #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)) 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_CALL() std::move(std::get<0>(_Adapter_value))
#define MODERN_CALLBACK_RETURN() return std::move(std::get<1>(_Adapter_value)).get() #define MODERN_CALLBACK_RETURN() return std::move(std::get<1>(_Adapter_value)).get()

Načítá se…
Zrušit
Uložit