Browse Source

整理代码,以便于控制doxygen的结果

tags/v2.9.7
tearshark 4 years ago
parent
commit
7d40fa6d5e

+ 5
- 1
Doxyfile View File

EXCLUDE = channel_v1.h \ EXCLUDE = channel_v1.h \
event_v1.h \ event_v1.h \
mutex_v1.h
mutex_v1.h \
ring_queue.h \
ring_queue_lockfree.h \
ring_queue_spinlock.h \
intrusive_link_queue.h
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded # directories that are symbolic links (a Unix file system feature) are excluded

+ 48
- 8
librf/src/event_v2.h View File

struct [[nodiscard]] any_awaiter; struct [[nodiscard]] any_awaiter;


template<class _Iter template<class _Iter
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>)
> RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_any(_Iter begin_, _Iter end_) static auto wait_any(_Iter begin_, _Iter end_)
->any_awaiter<_Iter>; ->any_awaiter<_Iter>;


template<class _Cont template<class _Cont
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>)
> RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_any(_Cont& cnt_) static auto wait_any(_Cont& cnt_)
->any_awaiter<decltype(std::begin(cnt_))>; ->any_awaiter<decltype(std::begin(cnt_))>;


struct [[nodiscard]] timeout_any_awaiter; struct [[nodiscard]] timeout_any_awaiter;


template<class _Rep, class _Period, class _Iter template<class _Rep, class _Period, class _Iter
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>)
> RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_any_for(const std::chrono::duration<_Rep, _Period>& dt, _Iter begin_, _Iter end_) static auto wait_any_for(const std::chrono::duration<_Rep, _Period>& dt, _Iter begin_, _Iter end_)
->timeout_any_awaiter<_Iter>; ->timeout_any_awaiter<_Iter>;


template<class _Rep, class _Period, class _Cont template<class _Rep, class _Period, class _Cont
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>)
> RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_any_for(const std::chrono::duration<_Rep, _Period>& dt, _Cont& cnt_) static auto wait_any_for(const std::chrono::duration<_Rep, _Period>& dt, _Cont& cnt_)
->timeout_any_awaiter<decltype(std::begin(cnt_))>; ->timeout_any_awaiter<decltype(std::begin(cnt_))>;


struct [[nodiscard]] all_awaiter; struct [[nodiscard]] all_awaiter;


template<class _Iter template<class _Iter
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>)
> RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_all(_Iter begin_, _Iter end_) static auto wait_all(_Iter begin_, _Iter end_)
->all_awaiter<_Iter>; ->all_awaiter<_Iter>;


template<class _Cont template<class _Cont
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>)
> RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_all(_Cont& cnt_) static auto wait_all(_Cont& cnt_)
->all_awaiter<decltype(std::begin(cnt_))>; ->all_awaiter<decltype(std::begin(cnt_))>;


struct [[nodiscard]] timeout_all_awaiter; struct [[nodiscard]] timeout_all_awaiter;


template<class _Rep, class _Period, class _Iter template<class _Rep, class _Period, class _Iter
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_of_v<_Iter, event_t>)
> RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_IteratorOfT<_Iter, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_all_for(const std::chrono::duration<_Rep, _Period>& dt, _Iter begin_, _Iter end_) static auto wait_all_for(const std::chrono::duration<_Rep, _Period>& dt, _Iter begin_, _Iter end_)
->timeout_all_awaiter<_Iter>; ->timeout_all_awaiter<_Iter>;


template<class _Rep, class _Period, class _Cont template<class _Rep, class _Period, class _Cont
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>) COMMA_RESUMEF_ENABLE_IF(traits::is_container_of_v<_Cont, event_t>)
> RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
>
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(_ContainerOfT<_Cont, event_t>)
#endif //DOXYGEN_SKIP_PROPERTY
static auto wait_all_for(const std::chrono::duration<_Rep, _Period>& dt, _Cont& cnt_) static auto wait_all_for(const std::chrono::duration<_Rep, _Period>& dt, _Cont& cnt_)
->timeout_all_awaiter<decltype(std::begin(cnt_))>; ->timeout_all_awaiter<decltype(std::begin(cnt_))>;



+ 2
- 2
librf/src/event_v2.inl View File

lockes.emplace_back(std::ref(evt->_lock)); lockes.emplace_back(std::ref(evt->_lock));
} }
scoped_lock_range<ref_lock_type> lock_(lockes);
batch_lock_t<ref_lock_type> lock_(lockes);
for (auto iter = _begin; iter != _end; ++iter) for (auto iter = _begin; iter != _end; ++iter)
{ {
(void)_state->on_await_suspend(handler); (void)_state->on_await_suspend(handler);
cb(); cb();
scoped_lock_range<ref_lock_type> lock_(lockes);
batch_lock_t<ref_lock_type> lock_(lockes);
for (auto iter = _begin; iter != _end; ++iter) for (auto iter = _begin; iter != _end; ++iter)
{ {

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

}; };
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY
typedef generator_iterator<_Ty, promise_type> iterator;
using iterator = generator_iterator<_Ty, promise_type>;
iterator begin() iterator begin()
{ {

+ 12
- 12
librf/src/mutex_v2.h View File

{ {
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY
/** /**
* @brief 提示手工解锁,故相关的lock()函数不再返回scoped_unlock_t。
* @brief 提示手工解锁,故相关的lock()函数不再返回batch_unlock_t。
*/ */
struct adopt_manual_unlock_t{}; struct adopt_manual_unlock_t{};


/** /**
* @brief 提示手工解锁,故相关的lock()函数不再返回scoped_unlock_t。
* @brief 提示手工解锁,故相关的lock()函数不再返回batch_unlock_t。
*/ */
constexpr adopt_manual_unlock_t adopt_manual_unlock; constexpr adopt_manual_unlock_t adopt_manual_unlock;


* @brief 在析构的时候自动解锁mutex_t的辅助类。 * @brief 在析构的时候自动解锁mutex_t的辅助类。
*/ */
template<class... _Mtxs> template<class... _Mtxs>
struct [[nodiscard]] scoped_unlock_t;
struct [[nodiscard]] batch_unlock_t;


/** /**
* @brief 支持递归的锁。 * @brief 支持递归的锁。


/** /**
* @brief 在协程中加锁,如果不能立即获得锁,则阻塞当前协程。但不会阻塞当前线程。 * @brief 在协程中加锁,如果不能立即获得锁,则阻塞当前协程。但不会阻塞当前线程。
* @return [co_await] scoped_unlock_t
* @return [co_await] batch_unlock_t
*/ */
awaiter/*scoped_unlock_t*/ lock() const noexcept;
awaiter/*batch_unlock_t*/ lock() const noexcept;
/** /**
* @brief 等同调用 co_await lock()。 * @brief 等同调用 co_await lock()。
* @return [co_await] scoped_unlock_t
* @return [co_await] batch_unlock_t
*/ */
awaiter/*scoped_unlock_t*/ operator co_await() const noexcept;
awaiter/*batch_unlock_t*/ operator co_await() const noexcept;


/** /**
* @brief 在协程中加锁,如果不能立即获得锁,则阻塞当前协程。但不会阻塞当前线程。 * @brief 在协程中加锁,如果不能立即获得锁,则阻塞当前协程。但不会阻塞当前线程。
/** /**
* @brief 在协程中,无死锁的批量加锁。不会阻塞当前线程。直到获得所有锁之前,会阻塞当前协程。 * @brief 在协程中,无死锁的批量加锁。不会阻塞当前线程。直到获得所有锁之前,会阻塞当前协程。
* @param mtxs... 需要获得的锁列表。 * @param mtxs... 需要获得的锁列表。
* @return [co_await] scoped_unlock_t
* @return [co_await] batch_unlock_t
*/ */
template<class... _Mtxs template<class... _Mtxs
#ifndef DOXYGEN_SKIP_PROPERTY #ifndef DOXYGEN_SKIP_PROPERTY
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> , typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>>
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY
> >
static future_t<scoped_unlock_t<_Mtxs...>> lock(_Mtxs&... mtxs);
static future_t<batch_unlock_t<_Mtxs...>> lock(_Mtxs&... mtxs);


/** /**
* @brief 在协程中,无死锁的批量加锁。不会阻塞当前线程。直到获得所有锁之前,会阻塞当前协程。 * @brief 在协程中,无死锁的批量加锁。不会阻塞当前线程。直到获得所有锁之前,会阻塞当前协程。
* @brief 在非协程中,无死锁的批量加锁。会阻塞当前线程,直到获得所有锁为止。 * @brief 在非协程中,无死锁的批量加锁。会阻塞当前线程,直到获得所有锁为止。
* @param unique_address 代表获得锁的拥有者。 * @param unique_address 代表获得锁的拥有者。
* @param mtxs... 需要获得的锁列表。 * @param mtxs... 需要获得的锁列表。
* @return scoped_unlock_t
* @return batch_unlock_t
*/ */
template<class... _Mtxs template<class... _Mtxs
#ifndef DOXYGEN_SKIP_PROPERTY #ifndef DOXYGEN_SKIP_PROPERTY
, typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>> , typename = std::enable_if_t<std::conjunction_v<std::is_same<remove_cvref_t<_Mtxs>, mutex_t>...>>
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY
> >
static scoped_unlock_t<_Mtxs...> lock(void* unique_address, _Mtxs&... mtxs);
static batch_unlock_t<_Mtxs...> lock(void* unique_address, _Mtxs&... mtxs);


/** /**
* @brief 在非协程中,无死锁的批量加锁。会阻塞当前线程,直到获得所有锁为止。 * @brief 在非协程中,无死锁的批量加锁。会阻塞当前线程,直到获得所有锁为止。
private: private:
struct _MutexAwaitAssembleT; struct _MutexAwaitAssembleT;


template<class... _Mtxs> friend struct scoped_unlock_t;
template<class... _Mtxs> friend struct batch_unlock_t;


mutex_impl_ptr _mutex; mutex_impl_ptr _mutex;
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY

+ 30
- 28
librf/src/mutex_v2.inl View File

inline namespace mutex_v2 inline namespace mutex_v2
{ {
template<> template<>
struct [[nodiscard]] scoped_unlock_t<mutex_t>
struct [[nodiscard]] batch_unlock_t<mutex_t>
{ {
typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr; typedef std::shared_ptr<detail::mutex_v2_impl> mutex_impl_ptr;


scoped_unlock_t()
batch_unlock_t()
: _owner(nullptr) : _owner(nullptr)
{} {}


//此函数,应该在try_lock()获得锁后使用 //此函数,应该在try_lock()获得锁后使用
//或者在协程里,由awaiter使用 //或者在协程里,由awaiter使用
scoped_unlock_t(std::adopt_lock_t, void* sch, mutex_impl_ptr mtx)
batch_unlock_t(std::adopt_lock_t, void* sch, mutex_impl_ptr mtx)
: _mutex(std::move(mtx)) : _mutex(std::move(mtx))
, _owner(sch) , _owner(sch)
{} {}


batch_unlock_t(std::adopt_lock_t, void* sch, const mutex_t& mtx)
: batch_unlock_t(std::adopt_lock, sch, mtx._mutex)
{}

/*
//此函数,适合在非协程里使用 //此函数,适合在非协程里使用
scoped_unlock_t(void* sch, mutex_impl_ptr mtx)
batch_unlock_t(void* sch, mutex_impl_ptr mtx)
: _mutex(std::move(mtx)) : _mutex(std::move(mtx))
, _owner(sch) , _owner(sch)
{ {
_mutex->lock_until_succeed(sch); _mutex->lock_until_succeed(sch);
} }



scoped_unlock_t(std::adopt_lock_t, void* sch, const mutex_t& mtx)
: scoped_unlock_t(std::adopt_lock, sch, mtx._mutex)
{}
scoped_unlock_t(void* sch, const mutex_t& mtx)
: scoped_unlock_t(sch, mtx._mutex)
batch_unlock_t(void* sch, const mutex_t& mtx)
: batch_unlock_t(sch, mtx._mutex)
{} {}
*/


~scoped_unlock_t()
~batch_unlock_t()
{ {
if (_mutex != nullptr) if (_mutex != nullptr)
_mutex->unlock(_owner); _mutex->unlock(_owner);
} }
} }


scoped_unlock_t(const scoped_unlock_t&) = delete;
scoped_unlock_t& operator = (const scoped_unlock_t&) = delete;
scoped_unlock_t(scoped_unlock_t&& _Right) = default;
scoped_unlock_t& operator = (scoped_unlock_t&& _Right) = default;
batch_unlock_t(const batch_unlock_t&) = delete;
batch_unlock_t& operator = (const batch_unlock_t&) = delete;
batch_unlock_t(batch_unlock_t&& _Right) = default;
batch_unlock_t& operator = (batch_unlock_t&& _Right) = default;
private: private:
mutex_impl_ptr _mutex; mutex_impl_ptr _mutex;
void* _owner; void* _owner;
{ {
return await_suspend2(handler, []{}); return await_suspend2(handler, []{});
} }
scoped_unlock_t<mutex_t> await_resume() noexcept
batch_unlock_t<mutex_t> await_resume() noexcept
{ {
mutex_impl_ptr mtx = _mutex ? _mutex->shared_from_this() : nullptr; mutex_impl_ptr mtx = _mutex ? _mutex->shared_from_this() : nullptr;
_mutex = nullptr; _mutex = nullptr;
}; };


template<class... _Mtxs> template<class... _Mtxs>
struct [[nodiscard]] scoped_unlock_t
struct [[nodiscard]] batch_unlock_t
{ {
mutex_t::_MutexAwaitAssembleT _MAA; mutex_t::_MutexAwaitAssembleT _MAA;


template<class... U> template<class... U>
scoped_unlock_t(std::adopt_lock_t, void* sch, U&&... mtxs)
batch_unlock_t(std::adopt_lock_t, void* sch, U&&... mtxs)
: _MAA(sch, std::forward<U>(mtxs)...) : _MAA(sch, std::forward<U>(mtxs)...)
{} {}


~scoped_unlock_t()
~batch_unlock_t()
{ {
if (_MAA._owner != nullptr) if (_MAA._owner != nullptr)
{ {
} }
} }


scoped_unlock_t(const scoped_unlock_t&) = delete;
scoped_unlock_t& operator = (const scoped_unlock_t&) = delete;
scoped_unlock_t(scoped_unlock_t&& _Right) = default;
scoped_unlock_t& operator = (scoped_unlock_t&& _Right) = default;
batch_unlock_t(const batch_unlock_t&) = delete;
batch_unlock_t& operator = (const batch_unlock_t&) = delete;
batch_unlock_t(batch_unlock_t&& _Right) = default;
batch_unlock_t& operator = (batch_unlock_t&& _Right) = default;
}; };


template<class... _Mtxs> template<class... _Mtxs>
scoped_unlock_t()->scoped_unlock_t<_Mtxs...>;
batch_unlock_t()->batch_unlock_t<_Mtxs...>;


template<class... _Mtxs, typename> template<class... _Mtxs, typename>
inline future_t<scoped_unlock_t<_Mtxs...>> mutex_t::lock(_Mtxs&... mtxs)
inline future_t<batch_unlock_t<_Mtxs...>> mutex_t::lock(_Mtxs&... mtxs)
{ {
scoped_unlock_t<_Mtxs...> unlock_guard{ std::adopt_lock, root_state(), mtxs... };
batch_unlock_t<_Mtxs...> unlock_guard{ std::adopt_lock, root_state(), mtxs... };
co_await detail::mutex_lock_await_lock_impl::_Lock_range(unlock_guard._MAA); co_await detail::mutex_lock_await_lock_impl::_Lock_range(unlock_guard._MAA);
co_return std::move(unlock_guard); co_return std::move(unlock_guard);
} }
} }


template<class... _Mtxs, typename> template<class... _Mtxs, typename>
inline scoped_unlock_t<_Mtxs...> mutex_t::lock(void* unique_address, _Mtxs&... mtxs)
inline batch_unlock_t<_Mtxs...> mutex_t::lock(void* unique_address, _Mtxs&... mtxs)
{ {
assert(unique_address != nullptr); assert(unique_address != nullptr);


detail::_MutexAddressAssembleT _MAA{ unique_address, mtxs... }; detail::_MutexAddressAssembleT _MAA{ unique_address, mtxs... };
detail::scoped_lock_range_lock_impl::_Lock_range(_MAA); detail::scoped_lock_range_lock_impl::_Lock_range(_MAA);
scoped_unlock_t<_Mtxs...> su{ std::adopt_lock, unique_address };
batch_unlock_t<_Mtxs...> su{ std::adopt_lock, unique_address };
su._MAA._mutex = std::move(_MAA._mutex); su._MAA._mutex = std::move(_MAA._mutex);
return su; return su;
} }

+ 16
- 10
librf/src/scheduler.h View File

#pragma once #pragma once
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_NS RESUMEF_NS
{ {
struct local_scheduler; struct local_scheduler;
#endif //DOXYGEN_SKIP_PROPERTY
struct scheduler_t : public std::enable_shared_from_this<scheduler_t> struct scheduler_t : public std::enable_shared_from_this<scheduler_t>
{ {
private:
using state_sptr = counted_ptr<state_base_t>; using state_sptr = counted_ptr<state_base_t>;
using state_vector = std::vector<state_sptr>; using state_vector = std::vector<state_sptr>;
private:
using lock_type = std::recursive_mutex;
using lock_type = spinlock;
using task_dictionary_type = std::unordered_map<state_base_t*, std::unique_ptr<task_base_t>>; using task_dictionary_type = std::unordered_map<state_base_t*, std::unique_ptr<task_base_t>>;
mutable spinlock _lock_running; mutable spinlock _lock_running;
void new_task(task_base_t* task); void new_task(task_base_t* task);
//void cancel_all_task_(); //void cancel_all_task_();
public: public:
void run_one_batch(); void run_one_batch();
void run_until_notask(); void run_until_notask();
//void break_all(); //void break_all();
template<class _Ty template<class _Ty
#ifndef DOXYGEN_SKIP_PROPERTY
COMMA_RESUMEF_ENABLE_IF(traits::is_callable_v<_Ty> || traits::is_future_v<_Ty> || traits::is_generator_v<_Ty>) COMMA_RESUMEF_ENABLE_IF(traits::is_callable_v<_Ty> || traits::is_future_v<_Ty> || traits::is_generator_v<_Ty>)
#endif //DOXYGEN_SKIP_PROPERTY
> >
RESUMEF_REQUIRES(traits::is_callable_v<_Ty> || traits::is_future_v<_Ty> || traits::is_generator_v<_Ty>)
inline void operator + (_Ty&& t_)
#ifndef DOXYGEN_SKIP_PROPERTY
RESUMEF_REQUIRES(traits::is_callable_v<_Ty> || traits::is_future_v<_Ty> || traits::is_generator_v<_Ty>)
#endif //DOXYGEN_SKIP_PROPERTY
void operator + (_Ty&& t_)
{ {
if constexpr (traits::is_callable_v<_Ty>) if constexpr (traits::is_callable_v<_Ty>)
new_task(new ctx_task_t<_Ty>(t_)); new_task(new ctx_task_t<_Ty>(t_));
new_task(new task_t<_Ty>(t_)); new_task(new task_t<_Ty>(t_));
} }
inline bool empty() const
bool empty() const
{ {
scoped_lock<spinlock, spinlock> __guard(_lock_ready, _lock_running); scoped_lock<spinlock, spinlock> __guard(_lock_ready, _lock_running);
return _ready_task.empty() && _runing_states.empty() && _timer->empty(); return _ready_task.empty() && _runing_states.empty() && _timer->empty();
} }
inline timer_manager* timer() const noexcept
timer_manager* timer() const noexcept
{ {
return _timer.get(); return _timer.get();
} }
#ifndef DOXYGEN_SKIP_PROPERTY
void add_generator(state_base_t* sptr); void add_generator(state_base_t* sptr);
void del_final(state_base_t* sptr); void del_final(state_base_t* sptr);
std::unique_ptr<task_base_t> del_switch(state_base_t* sptr); std::unique_ptr<task_base_t> del_switch(state_base_t* sptr);
scheduler_t& operator = (const scheduler_t&) = delete; scheduler_t& operator = (const scheduler_t&) = delete;
static scheduler_t g_scheduler; static scheduler_t g_scheduler;
#endif //DOXYGEN_SKIP_PROPERTY
}; };
struct local_scheduler struct local_scheduler
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()
return &scheduler_t::g_scheduler; return &scheduler_t::g_scheduler;
} }
#endif #endif
//--------------------------------------------------------------------------------------------------
} }

+ 12
- 10
librf/src/spinlock.h View File

} }
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY
// class with destructor that unlocks mutexes
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 scoped_lock_range { // class with destructor that unlocks mutexes
class batch_lock_t
{
public: public:
explicit scoped_lock_range(_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);
} }
explicit scoped_lock_range(_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);
} }
explicit scoped_lock_range(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
} }
explicit scoped_lock_range(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
} }
~scoped_lock_range() 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);
} }
} }
scoped_lock_range(const scoped_lock_range&) = delete;
scoped_lock_range& operator=(const scoped_lock_range&) = delete;
batch_lock_t(const batch_lock_t&) = delete;
batch_lock_t& operator=(const batch_lock_t&) = delete;
scoped_lock_range(scoped_lock_range&& _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;
} }
scoped_lock_range& operator=(scoped_lock_range&& _Right)
batch_lock_t& operator=(batch_lock_t&& _Right)
{ {
if (this != &_Right) if (this != &_Right)
{ {

+ 5
- 5
tutorial/test_async_mutex.cpp View File

for (size_t i = 0; i < N / 2; ++i) for (size_t i = 0; i < N / 2; ++i)
{ {
{ {
scoped_unlock_t _locker = co_await g_lock.lock(); //_locker析构后,会调用对应的unlock()函数。
batch_unlock_t _locker = co_await g_lock.lock(); //_locker析构后,会调用对应的unlock()函数。
--g_counter; --g_counter;
std::cout << "pop :" << g_counter << " on " << idx << std::endl; std::cout << "pop :" << g_counter << " on " << idx << std::endl;
co_await 50ms; co_await 50ms;
scoped_unlock_t _locker_2 = co_await g_lock;
batch_unlock_t _locker_2 = co_await g_lock;
--g_counter; --g_counter;
std::cout << "pop :" << g_counter << " on " << idx << std::endl; std::cout << "pop :" << g_counter << " on " << idx << std::endl;
for (size_t i = 0; i < N; ++i) for (size_t i = 0; i < N; ++i)
{ {
{ {
scoped_unlock_t _locker = co_await g_lock.lock();
batch_unlock_t _locker = co_await g_lock.lock();
++g_counter; ++g_counter;
std::cout << "push:" << g_counter << " on " << idx << std::endl; std::cout << "push:" << g_counter << " on " << idx << std::endl;
{ {
if (g_lock.try_lock_for(500ms, &provide_unique_address)) if (g_lock.try_lock_for(500ms, &provide_unique_address))
{ {
scoped_unlock_t _locker(std::adopt_lock, &provide_unique_address, g_lock);
batch_unlock_t _locker(std::adopt_lock, &provide_unique_address, g_lock);
++g_counter; ++g_counter;
std::cout << "push:" << g_counter << " on " << idx << std::endl; std::cout << "push:" << g_counter << " on " << idx << std::endl;
{ {
for (int i = 0; i < 10000; ++i) for (int i = 0; i < 10000; ++i)
{ {
scoped_unlock_t __lockers = co_await mutex_t::lock(a, b, c);
batch_unlock_t __lockers = co_await mutex_t::lock(a, b, c);
assert(a.is_locked()); assert(a.is_locked());
assert(b.is_locked()); assert(b.is_locked());
assert(c.is_locked()); assert(c.is_locked());

Loading…
Cancel
Save