*.vhdl \ | *.vhdl \ | ||||
*.ucf \ | *.ucf \ | ||||
*.qsf \ | *.qsf \ | ||||
*.ice | |||||
*.ice \ | |||||
*.inl | |||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should | # The RECURSIVE tag can be used to specify whether or not subdirectories should | ||||
# be searched for input files as well. | # be searched for input files as well. |
namespace asio { | namespace asio { | ||||
/** | |||||
* @brief 用于指示asio相关异步函数,返回resumef::future_t<>的类型,从而变成支持 librf 的协程函数。 | |||||
*/ | |||||
template <typename Executor = executor> | template <typename Executor = executor> | ||||
struct rf_task_t | struct rf_task_t | ||||
{ | { | ||||
ASIO_CONSTEXPR rf_task_t() {} | ASIO_CONSTEXPR rf_task_t() {} | ||||
}; | }; | ||||
/** | |||||
* @brief 用于指示asio相关异步函数,返回resumef::future_t<>的常量,从而变成支持 librf 的协程函数。 | |||||
*/ | |||||
constexpr rf_task_t<> rf_task; | constexpr rf_task_t<> rf_task; | ||||
namespace librf { | namespace librf { |
#pragma once | |||||
#pragma once | |||||
namespace resumef | namespace resumef | ||||
{ | { | ||||
/** | |||||
* @brief awaitable_t<>的公共实现部分,用于减少awaitable_t<>的重复代码。 | |||||
* @param _Ty 可等待函数(awaitable function)的返回类型。 | |||||
* @see 参见awaitable_t<>类的说明。 | |||||
*/ | |||||
template<class _Ty> | template<class _Ty> | ||||
struct awaitable_impl_t | struct awaitable_impl_t | ||||
{ | { | ||||
awaitable_impl_t& operator = (const awaitable_impl_t&) = default; | awaitable_impl_t& operator = (const awaitable_impl_t&) = default; | ||||
awaitable_impl_t& operator = (awaitable_impl_t&&) = default; | awaitable_impl_t& operator = (awaitable_impl_t&&) = default; | ||||
/** | |||||
* @brief 发生了异常后,设置异常。 | |||||
* @attention 与set_value()互斥。调用了set_exception(e)后,不能再调用set_value()。 | |||||
*/ | |||||
void set_exception(std::exception_ptr e) const | void set_exception(std::exception_ptr e) const | ||||
{ | { | ||||
this->_state->set_exception(std::move(e)); | this->_state->set_exception(std::move(e)); | ||||
this->_state = nullptr; | this->_state = nullptr; | ||||
} | } | ||||
/** | |||||
* @brief 在协程内部,重新抛出之前设置的异常。 | |||||
*/ | |||||
template<class _Exp> | template<class _Exp> | ||||
void throw_exception(_Exp e) const | void throw_exception(_Exp e) const | ||||
{ | { | ||||
set_exception(std::make_exception_ptr(std::move(e))); | set_exception(std::make_exception_ptr(std::move(e))); | ||||
} | } | ||||
/** | |||||
* @brief 获得与之关联的future_t<>对象,作为可等待函数(awaitable function)的返回值。 | |||||
*/ | |||||
future_type get_future() noexcept | future_type get_future() noexcept | ||||
{ | { | ||||
return future_type{ this->_state }; | return future_type{ this->_state }; | ||||
} | } | ||||
/** | |||||
* @brief 管理的state_t<>对象。 | |||||
*/ | |||||
mutable counted_ptr<state_type> _state = state_future_t::_Alloc_state<state_type>(true); | mutable counted_ptr<state_type> _state = state_future_t::_Alloc_state<state_type>(true); | ||||
}; | }; | ||||
/** | |||||
* @brief 用于包装‘异步函数’为‘可等待函数(awaitable function)’。 | |||||
* @details 通过返回一个‘可等待对象(awaitor)’,符合C++ coroutines的co_await所需的接口,来达成‘可等待函数(awaitable function)’。\n | |||||
* 这是扩展异步函数支持协程的重要手段。\n | |||||
* \n | |||||
* 典型用法是申明一个 awaitable_t<>局部变量 awaitable,\n | |||||
* 在已经获得结果的情况下,直接调用 awaitable.set_value(value)设置返回值,使得可等待函数立即获得结果。\n | |||||
* 在不能立即获得结果的情况下,通过在异步的回调lambda里,捕获awaitable局部变量,\n | |||||
* 根据异步结果,要么调用 awaitable.set_value(value)设置结果值,要么调用 awaitable.set_exception(e)设置异常。\n | |||||
* 在设置值或者异常后,调用可等待函数的协程将得以继续执行。\n | |||||
* 此可等待函数通过 awaitable.get_future()返回与之关联的 future_t<>对象,作为协程的可等待对象。\n | |||||
* \n | |||||
* @param _Ty 可等待函数(awaitable function)的返回类型。\n | |||||
* 要求至少支持移动构造和移动赋值。\n | |||||
* _Ty 支持特化为 _Ty&,以及 void。 | |||||
*/ | |||||
template<class _Ty> | template<class _Ty> | ||||
struct [[nodiscard]] awaitable_t : public awaitable_impl_t<_Ty> | struct [[nodiscard]] awaitable_t : public awaitable_impl_t<_Ty> | ||||
{ | { | ||||
using typename awaitable_impl_t<_Ty>::value_type; | using typename awaitable_impl_t<_Ty>::value_type; | ||||
using awaitable_impl_t<_Ty>::awaitable_impl_t; | using awaitable_impl_t<_Ty>::awaitable_impl_t; | ||||
/** | |||||
* @brief 设置可等待函数的返回值。 | |||||
* @details _Ty的void特化版本,则是不带参数的set_value()函数。 | |||||
* @param value 返回值。必须支持通过value构造出_Ty类型。 | |||||
* @attention 与set_exception()互斥。调用了set_value(value)后,不能再调用set_exception(e)。 | |||||
*/ | |||||
template<class U> | template<class U> | ||||
void set_value(U&& value) const | void set_value(U&& value) const | ||||
{ | { |
/** | /** | ||||
* @brief 在协程中从channel_t里读取一个数据。 | * @brief 在协程中从channel_t里读取一个数据。 | ||||
* @see 参考read()函数 | * @see 参考read()函数 | ||||
* @return [co_await] value_type | |||||
*/ | */ | ||||
read_awaiter operator co_await() const noexcept; | read_awaiter operator co_await() const noexcept; | ||||
namespace resumef | namespace resumef | ||||
{ | { | ||||
/** | |||||
* @brief 专用与state的智能计数指针,通过管理state内嵌的引用计数来管理state的生存期。 | |||||
*/ | |||||
template <typename T> | template <typename T> | ||||
struct counted_ptr | struct counted_ptr | ||||
{ | { | ||||
/** | |||||
* @brief 构造一个无内容的计数指针。 | |||||
*/ | |||||
counted_ptr() noexcept = default; | counted_ptr() noexcept = default; | ||||
counted_ptr(const counted_ptr& cp) : _p(cp._p) | |||||
/** | |||||
* @brief 拷贝构造函数。 | |||||
*/ | |||||
counted_ptr(const counted_ptr& cp) : _p(cp._p) | |||||
{ | { | ||||
_lock(); | _lock(); | ||||
} | } | ||||
counted_ptr(T* p) : _p(p) | |||||
/** | |||||
* @brief 通过裸指针构造一个计数指针。 | |||||
*/ | |||||
counted_ptr(T* p) : _p(p) | |||||
{ | { | ||||
_lock(); | _lock(); | ||||
} | } | ||||
/** | |||||
* @brief 移动构造函数。 | |||||
*/ | |||||
counted_ptr(counted_ptr&& cp) noexcept | counted_ptr(counted_ptr&& cp) noexcept | ||||
{ | { | ||||
std::swap(_p, cp._p); | std::swap(_p, cp._p); | ||||
} | } | ||||
counted_ptr& operator=(const counted_ptr& cp) | |||||
/** | |||||
* @brief 拷贝赋值函数。 | |||||
*/ | |||||
counted_ptr& operator=(const counted_ptr& cp) | |||||
{ | { | ||||
if (&cp != this) | if (&cp != this) | ||||
{ | { | ||||
return *this; | return *this; | ||||
} | } | ||||
/** | |||||
* @brief 移动赋值函数。 | |||||
*/ | |||||
counted_ptr& operator=(counted_ptr&& cp) noexcept | counted_ptr& operator=(counted_ptr&& cp) noexcept | ||||
{ | { | ||||
if (&cp != this) | if (&cp != this) | ||||
return *this; | return *this; | ||||
} | } | ||||
/** | |||||
* @brief 析构函数中自动做一个计数减一操作。计数减为0,则删除state对象。 | |||||
*/ | |||||
~counted_ptr() | ~counted_ptr() | ||||
{ | { | ||||
_unlock(); | _unlock(); | ||||
} | } | ||||
/** | |||||
* @brief 重载指针操作符。 | |||||
*/ | |||||
T* operator->() const noexcept | T* operator->() const noexcept | ||||
{ | { | ||||
return _p; | return _p; | ||||
} | } | ||||
/** | |||||
* @brief 获得管理的state指针。 | |||||
*/ | |||||
T* get() const noexcept | T* get() const noexcept | ||||
{ | { | ||||
return _p; | return _p; | ||||
} | } | ||||
/** | |||||
* @brief 重置为空指针。 | |||||
*/ | |||||
void reset() | void reset() | ||||
{ | { | ||||
_unlock(); | _unlock(); |
scheduler_t* _scheduler; | scheduler_t* _scheduler; | ||||
}; | }; | ||||
/** | |||||
* @brief 获得当前协程绑定的调度器。 | |||||
* @details 立即返回,没有协程切换和等待。 | |||||
* @return [co_await] scheduler_t* | |||||
*/ | |||||
inline get_current_scheduler_awaitor get_current_scheduler() | inline get_current_scheduler_awaitor get_current_scheduler() | ||||
{ | { | ||||
return {}; | return {}; | ||||
state_base_t* _state; | state_base_t* _state; | ||||
}; | }; | ||||
/** | |||||
* @brief 获得当前协程的跟state指针。 | |||||
* @details 立即返回,没有协程切换和等待。 | |||||
* @return [co_await] state_base_t* | |||||
*/ | |||||
inline get_root_state_awaitor get_root_state() | inline get_root_state_awaitor get_root_state() | ||||
{ | { | ||||
return {}; | return {}; |
#pragma once | |||||
#pragma once | |||||
namespace resumef | namespace resumef | ||||
{ | { | ||||
/** | |||||
* @brief 错误ç �。 | |||||
*/ | |||||
enum struct error_code | enum struct error_code | ||||
{ | { | ||||
none, | none, | ||||
not_ready, // get_value called when value not available | |||||
already_acquired, // attempt to get another future | |||||
unlock_more, // unlock ´ÎÊý¶àÓàlock´ÎÊý | |||||
read_before_write, // 0ÈÝÁ¿µÄchannel£¬ÏȶÁºóд | |||||
timer_canceled, // ¶¨Ê±Æ÷±»ÒâÍâÈ¡Ïû | |||||
not_await_lock, // ûÓÐÔÚгÌÖÐʹÓÃco_awaitµÈ´ýlock½á¹û | |||||
not_ready, ///< get_value called when value not available | |||||
already_acquired, ///< attempt to get another future | |||||
unlock_more, ///< unlock 次数多余lock次数 | |||||
read_before_write, ///< 0容�的channel,先读�写 | |||||
timer_canceled, ///< 定时器被�外�消 | |||||
not_await_lock, ///< 没有在å��程ä¸ä½¿ç”¨co_awaitç‰å¾…lock结果 | |||||
max__ | max__ | ||||
}; | }; | ||||
/** | |||||
* @brief 通过错误ç �获得错误æ��è¿°å—符串。 | |||||
*/ | |||||
const char* get_error_string(error_code fe, const char* classname); | const char* get_error_string(error_code fe, const char* classname); | ||||
/** | |||||
* @brief 在�作future_t<>时产生的异常。 | |||||
*/ | |||||
const char* get_error_string(error_code fe, const char* classname); | |||||
struct future_exception : std::logic_error | struct future_exception : std::logic_error | ||||
{ | { | ||||
error_code _error; | error_code _error; | ||||
} | } | ||||
}; | }; | ||||
struct lock_exception : std::logic_error | |||||
/** | |||||
* @brief 错误使用mutex_t时产生的异常。 | |||||
*/ | |||||
struct mutex_exception : std::logic_error | |||||
{ | { | ||||
error_code _error; | error_code _error; | ||||
lock_exception(error_code fe) | |||||
: logic_error(get_error_string(fe, "lock_exception")) | |||||
mutex_exception(error_code fe) | |||||
: logic_error(get_error_string(fe, "mutex_exception")) | |||||
, _error(fe) | , _error(fe) | ||||
{ | { | ||||
} | } | ||||
}; | }; | ||||
/** | |||||
* @brief 错误使用channel_t时产生的异常(v2版本已ç»�ä¸�å†�抛æ¤å¼‚常了)。 | |||||
*/ | |||||
struct channel_exception : std::logic_error | struct channel_exception : std::logic_error | ||||
{ | { | ||||
error_code _error; | error_code _error; | ||||
} | } | ||||
}; | }; | ||||
/** | |||||
* @brief 定时器���消导致的异常。 | |||||
*/ | |||||
struct timer_canceled_exception : public std::logic_error | struct timer_canceled_exception : public std::logic_error | ||||
{ | { | ||||
error_code _error; | error_code _error; |
namespace resumef | namespace resumef | ||||
{ | { | ||||
/** | |||||
* @brief 用于resumef协程的返回值。 | |||||
* @details 由于coroutines的限制,协程的返回值必须明确申明,而不能通过auto推导。\n | |||||
* 用在恢复函数(resumeable function)里,支持co_await和co_yield。\n | |||||
* 用在可等待函数(awaitable function)里,与awaitable_t<>配套使用。 | |||||
*/ | |||||
template<class _Ty> | template<class _Ty> | ||||
struct [[nodiscard]] future_t | struct [[nodiscard]] future_t | ||||
{ | { |
/* | |||||
/* | |||||
* Modify from <experimental/generator_t.h> | * Modify from <experimental/generator_t.h> | ||||
* Purpose: Library support of coroutines. generator_t class | * Purpose: Library support of coroutines. generator_t class | ||||
* http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0057r0.pdf | * http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0057r0.pdf | ||||
}; | }; | ||||
#endif //DOXYGEN_SKIP_PROPERTY | #endif //DOXYGEN_SKIP_PROPERTY | ||||
/** | |||||
* @brief 专用于co_yield函数。 | |||||
*/ | |||||
template <typename _Ty, typename _Alloc> | template <typename _Ty, typename _Alloc> | ||||
struct generator_t | struct generator_t | ||||
{ | { | ||||
std::cout << " generator_promise::new, return ptr=" << (void*)_Rptr << std::endl; | std::cout << " generator_promise::new, return ptr=" << (void*)_Rptr << std::endl; | ||||
#endif | #endif | ||||
//ÔÚ³õʼµØÖ·ÉϹ¹Ôìstate | |||||
//在åˆ�始地å�€ä¸Šæž„é€ state | |||||
{ | { | ||||
state_type* st = state_type::_Construct(ptr); | state_type* st = state_type::_Construct(ptr); | ||||
st->lock(); | st->lock(); |
assert(_mutex == nullptr); | assert(_mutex == nullptr); | ||||
if (_mutex != nullptr) | if (_mutex != nullptr) | ||||
{ | { | ||||
throw lock_exception(error_code::not_await_lock); | |||||
throw mutex_exception(error_code::not_await_lock); | |||||
} | } | ||||
} | } | ||||
assert(_mutex == nullptr); | assert(_mutex == nullptr); | ||||
if (_mutex != nullptr) | if (_mutex != nullptr) | ||||
{ | { | ||||
throw lock_exception(error_code::not_await_lock); | |||||
throw mutex_exception(error_code::not_await_lock); | |||||
} | } | ||||
} | } | ||||
assert(_mutex == nullptr); | assert(_mutex == nullptr); | ||||
if (_mutex != nullptr) | if (_mutex != nullptr) | ||||
{ | { | ||||
throw lock_exception(error_code::not_await_lock); | |||||
throw mutex_exception(error_code::not_await_lock); | |||||
} | } | ||||
} | } | ||||
namespace resumef | namespace resumef | ||||
{ | { | ||||
/** | |||||
* @brief 协程专用的睡眠功能。 | |||||
* @details 不能使用操作系统提供的sleep功能,因为会阻塞协程。\n | |||||
* 此函数不会阻塞线程,仅仅将当前协程挂起,直到指定时刻。\n | |||||
* 其精度,取决与调度器循环的精度,以及std::chrono::system_clock的精度。简而言之,可以认为只要循环够快,精度到100ns。 | |||||
* @return [co_await] void | |||||
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 | |||||
*/ | |||||
future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_); | future_t<> sleep_until_(std::chrono::system_clock::time_point tp_, scheduler_t& scheduler_); | ||||
/** | |||||
* @brief 协程专用的睡眠功能。 | |||||
* @see 参考sleep_until_()函数\n | |||||
* @return [co_await] void | |||||
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 | |||||
*/ | |||||
inline future_t<> sleep_for_(std::chrono::system_clock::duration dt_, scheduler_t& scheduler_) | inline future_t<> sleep_for_(std::chrono::system_clock::duration dt_, scheduler_t& scheduler_) | ||||
{ | { | ||||
return sleep_until_(std::chrono::system_clock::now() + dt_, scheduler_); | return sleep_until_(std::chrono::system_clock::now() + dt_, scheduler_); | ||||
} | } | ||||
/** | |||||
* @brief 协程专用的睡眠功能。 | |||||
* @see 参考sleep_until_()函数\n | |||||
* @return [co_await] void | |||||
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 | |||||
*/ | |||||
template<class _Rep, class _Period> | template<class _Rep, class _Period> | ||||
inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_, scheduler_t& scheduler_) | inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_, scheduler_t& scheduler_) | ||||
{ | { | ||||
return sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), scheduler_); | return sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), scheduler_); | ||||
} | } | ||||
/** | |||||
* @brief 协程专用的睡眠功能。 | |||||
* @see 参考sleep_until_()函数\n | |||||
* @return [co_await] void | |||||
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 | |||||
*/ | |||||
template<class _Clock, class _Duration = typename _Clock::duration> | template<class _Clock, class _Duration = typename _Clock::duration> | ||||
inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_, scheduler_t& scheduler_) | inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_, scheduler_t& scheduler_) | ||||
{ | { | ||||
return sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), scheduler_); | return sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), scheduler_); | ||||
} | } | ||||
/** | |||||
* @brief 协程专用的睡眠功能。 | |||||
* @see 参考sleep_until_()函数\n | |||||
* @return [co_await] void | |||||
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 | |||||
*/ | |||||
template<class _Rep, class _Period> | template<class _Rep, class _Period> | ||||
inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_) | inline future_t<> sleep_for(std::chrono::duration<_Rep, _Period> dt_) | ||||
{ | { | ||||
scheduler_t* sch = current_scheduler(); | scheduler_t* sch = current_scheduler(); | ||||
co_await sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), *sch); | co_await sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), *sch); | ||||
} | } | ||||
/** | |||||
* @brief 协程专用的睡眠功能。 | |||||
* @see 参考sleep_until_()函数\n | |||||
* @return [co_await] void | |||||
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 | |||||
*/ | |||||
template<class _Clock, class _Duration> | template<class _Clock, class _Duration> | ||||
inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_) | inline future_t<> sleep_until(std::chrono::time_point<_Clock, _Duration> tp_) | ||||
{ | { | ||||
co_await sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), *sch); | co_await sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), *sch); | ||||
} | } | ||||
/** | |||||
* @brief 协程专用的睡眠功能。 | |||||
* @see 等同调用sleep_for(dt)\n | |||||
* @return [co_await] void | |||||
* @throw timer_canceled_exception 如果定时器被取消,则抛此异常。 | |||||
*/ | |||||
template <class Rep, class Period> | template <class Rep, class Period> | ||||
inline future_t<> operator co_await(std::chrono::duration<Rep, Period> dt_) | inline future_t<> operator co_await(std::chrono::duration<Rep, Period> dt_) | ||||
{ | { |
using spinlock = RESUMEF_USE_CUSTOM_SPINLOCK; | using spinlock = RESUMEF_USE_CUSTOM_SPINLOCK; | ||||
#else | #else | ||||
/** | |||||
* @brief 一个自旋锁实现。 | |||||
*/ | |||||
struct spinlock | struct spinlock | ||||
{ | { | ||||
static const size_t MAX_ACTIVE_SPIN = 4000; | static const size_t MAX_ACTIVE_SPIN = 4000; | ||||
std::thread::id owner_thread_id; | std::thread::id owner_thread_id; | ||||
#endif | #endif | ||||
/** | |||||
* @brief 初始为未加锁。 | |||||
*/ | |||||
spinlock() noexcept | spinlock() noexcept | ||||
{ | { | ||||
lck = FREE_VALUE; | lck = FREE_VALUE; | ||||
} | } | ||||
/** | |||||
* @brief 获得锁。会一直阻塞线程直到获得锁。 | |||||
*/ | |||||
void lock() noexcept | void lock() noexcept | ||||
{ | { | ||||
int val = FREE_VALUE; | int val = FREE_VALUE; | ||||
#endif | #endif | ||||
} | } | ||||
/** | |||||
* @brief 尝试获得锁一次。 | |||||
*/ | |||||
bool try_lock() noexcept | bool try_lock() noexcept | ||||
{ | { | ||||
int val = FREE_VALUE; | int val = FREE_VALUE; | ||||
return ret; | return ret; | ||||
} | } | ||||
/** | |||||
* @brief 释放锁。 | |||||
*/ | |||||
void unlock() noexcept | void unlock() noexcept | ||||
{ | { | ||||
#if _DEBUG | #if _DEBUG | ||||
} | } | ||||
#endif //DOXYGEN_SKIP_PROPERTY | #endif //DOXYGEN_SKIP_PROPERTY | ||||
// class with destructor that unlocks mutexes | |||||
/** | |||||
* @brief 无死锁的批量枷锁。 | |||||
* @param _Ty 锁的类型。例如std::mutex,resumef::spinlock,resumef::mutex_t(线程用法)均可。 | |||||
* @param _Cont 容纳一批锁的容器。 | |||||
* @param _Assemble 与_Cont配套的锁集合,特化了如何操作_Ty。 | |||||
*/ | |||||
template<class _Ty, class _Cont = std::vector<_Ty>, class _Assemble = detail::_LockVectorAssembleT<_Ty, _Cont>> | template<class _Ty, class _Cont = std::vector<_Ty>, class _Assemble = detail::_LockVectorAssembleT<_Ty, _Cont>> | ||||
class batch_lock_t | class batch_lock_t | ||||
{ | { | ||||
public: | public: | ||||
/** | |||||
* @brief 通过锁容器构造,并立刻应用加锁算法。 | |||||
*/ | |||||
explicit batch_lock_t(_Cont& locks_) | explicit batch_lock_t(_Cont& locks_) | ||||
: _LkN(&locks_) | : _LkN(&locks_) | ||||
, _LA(*_LkN) | , _LA(*_LkN) | ||||
{ | { | ||||
detail::scoped_lock_range_lock_impl::_Lock_range(_LA); | detail::scoped_lock_range_lock_impl::_Lock_range(_LA); | ||||
} | } | ||||
/** | |||||
* @brief 通过锁容器和锁集合构造,并立刻应用加锁算法。 | |||||
*/ | |||||
explicit batch_lock_t(_Cont& locks_, _Assemble& la_) | explicit batch_lock_t(_Cont& locks_, _Assemble& la_) | ||||
: _LkN(&locks_) | : _LkN(&locks_) | ||||
, _LA(la_) | , _LA(la_) | ||||
detail::scoped_lock_range_lock_impl::_Lock_range(_LA); | detail::scoped_lock_range_lock_impl::_Lock_range(_LA); | ||||
} | } | ||||
/** | |||||
* @brief 通过锁容器构造,容器里的锁已经全部获得。 | |||||
*/ | |||||
explicit batch_lock_t(std::adopt_lock_t, _Cont& locks_) | explicit batch_lock_t(std::adopt_lock_t, _Cont& locks_) | ||||
: _LkN(&locks_) | : _LkN(&locks_) | ||||
, _LA(*_LkN) | , _LA(*_LkN) | ||||
{ // construct but don't lock | { // construct but don't lock | ||||
} | } | ||||
/** | |||||
* @brief 通过锁容器和锁集合构造,容器里的锁已经全部获得。 | |||||
*/ | |||||
explicit batch_lock_t(std::adopt_lock_t, _Cont& locks_, _Assemble& la_) | explicit batch_lock_t(std::adopt_lock_t, _Cont& locks_, _Assemble& la_) | ||||
: _LkN(&locks_) | : _LkN(&locks_) | ||||
, _LA(la_) | , _LA(la_) | ||||
{ // construct but don't lock | { // construct but don't lock | ||||
} | } | ||||
/** | |||||
* @brief 析构函数里,释放容器里的锁。 | |||||
*/ | |||||
~batch_lock_t() noexcept | ~batch_lock_t() noexcept | ||||
{ | { | ||||
if (_LkN != nullptr) | if (_LkN != nullptr) | ||||
detail::scoped_lock_range_lock_impl::_Unlock_locks(0, (int)_LA.size(), _LA); | detail::scoped_lock_range_lock_impl::_Unlock_locks(0, (int)_LA.size(), _LA); | ||||
} | } | ||||
/** | |||||
* @brief 手工释放容器里的锁,析构函数里将不再有释放操作。 | |||||
*/ | |||||
void unlock() | void unlock() | ||||
{ | { | ||||
if (_LkN != nullptr) | if (_LkN != nullptr) | ||||
} | } | ||||
} | } | ||||
/** | |||||
* @brief 不支持拷贝构造。 | |||||
*/ | |||||
batch_lock_t(const batch_lock_t&) = delete; | batch_lock_t(const batch_lock_t&) = delete; | ||||
/** | |||||
* @brief 不支持拷贝赋值。 | |||||
*/ | |||||
batch_lock_t& operator=(const batch_lock_t&) = delete; | batch_lock_t& operator=(const batch_lock_t&) = delete; | ||||
/** | |||||
* @brief 支持移动构造。 | |||||
*/ | |||||
batch_lock_t(batch_lock_t&& _Right) | batch_lock_t(batch_lock_t&& _Right) | ||||
: _LkN(_Right._LkN) | : _LkN(_Right._LkN) | ||||
, _LA(std::move(_Right._LA)) | , _LA(std::move(_Right._LA)) | ||||
{ | { | ||||
_Right._LkN = nullptr; | _Right._LkN = nullptr; | ||||
} | } | ||||
/** | |||||
* @brief 支持移动赋值。 | |||||
*/ | |||||
batch_lock_t& operator=(batch_lock_t&& _Right) | batch_lock_t& operator=(batch_lock_t&& _Right) | ||||
{ | { | ||||
if (this != &_Right) | if (this != &_Right) |
namespace resumef | namespace resumef | ||||
{ | { | ||||
/** | |||||
* @brief state基类,state用于在协程的promise和future之间共享数据。 | |||||
*/ | |||||
struct state_base_t | struct state_base_t | ||||
{ | { | ||||
using _Alloc_char = std::allocator<char>; | using _Alloc_char = std::allocator<char>; | ||||
} | } | ||||
}; | }; | ||||
/** | |||||
* @brief 专用于generator_t<>的state类。 | |||||
*/ | |||||
struct state_generator_t : public state_base_t | struct state_generator_t : public state_base_t | ||||
{ | { | ||||
private: | private: | ||||
static state_generator_t* _Alloc_state(); | static state_generator_t* _Alloc_state(); | ||||
}; | }; | ||||
/** | |||||
* @brief 专用于future_t<>的state基类,实现了针对于future_t<>的公共方法等。 | |||||
*/ | |||||
struct state_future_t : public state_base_t | struct state_future_t : public state_base_t | ||||
{ | { | ||||
enum struct initor_type : uint8_t | enum struct initor_type : uint8_t | ||||
} | } | ||||
}; | }; | ||||
/** | |||||
* @brief 专用于future_t<>的state类。 | |||||
*/ | |||||
template <typename _Ty> | template <typename _Ty> | ||||
struct state_t final : public state_future_t | struct state_t final : public state_future_t | ||||
{ | { |
//is_container_v<T> | //is_container_v<T> | ||||
//判断是不是一个封闭区间的容器,或者数组。 | //判断是不是一个封闭区间的容器,或者数组。 | ||||
// | // | ||||
//is_container_of<T, E> | |||||
//is_container_of_v<T, E> | //is_container_of_v<T, E> | ||||
//判断是不是一个封闭区间的容器,或者数组。其元素类型是E。 | //判断是不是一个封闭区间的容器,或者数组。其元素类型是E。 | ||||
} | } | ||||
}; | }; | ||||
/** | |||||
* @fn 将本协程让渡出一次调用。 | |||||
* @return [co_await] void | |||||
*/ | |||||
inline yield_awaitor yield() | inline yield_awaitor yield() | ||||
{ | { | ||||
return {}; | return {}; |