mirror of
https://github.com/tearshark/librf.git
synced 2024-10-01 15:57:07 +08:00
timer提供线程安全的可能
This commit is contained in:
parent
cd8f6adb7e
commit
5ea36e6cc0
@ -26,6 +26,8 @@ RESUMEF_NS
|
|||||||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
|
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
|
||||||
{
|
{
|
||||||
*oldValue = false;
|
*oldValue = false;
|
||||||
|
_thandler.stop();
|
||||||
|
|
||||||
this->_coro = nullptr;
|
this->_coro = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,6 +38,7 @@ RESUMEF_NS
|
|||||||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
|
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
|
||||||
{
|
{
|
||||||
*oldValue = true;
|
*oldValue = true;
|
||||||
|
_thandler.stop();
|
||||||
|
|
||||||
assert(this->_scheduler != nullptr);
|
assert(this->_scheduler != nullptr);
|
||||||
if (this->_coro)
|
if (this->_coro)
|
||||||
@ -52,6 +55,7 @@ RESUMEF_NS
|
|||||||
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
|
if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel))
|
||||||
{
|
{
|
||||||
*oldValue = false;
|
*oldValue = false;
|
||||||
|
_thandler.reset();
|
||||||
|
|
||||||
assert(this->_scheduler != nullptr);
|
assert(this->_scheduler != nullptr);
|
||||||
if (this->_coro)
|
if (this->_coro)
|
||||||
|
@ -37,4 +37,18 @@ RESUMEF_NS
|
|||||||
timeout_awaiter wait_until_(const clock_type::time_point& tp) const noexcept;
|
timeout_awaiter wait_until_(const clock_type::time_point& tp) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class _Rep, class _Period>
|
||||||
|
auto wait_for(event_v2::event_t& e, const std::chrono::duration<_Rep, _Period>& dt)
|
||||||
|
{
|
||||||
|
return e.wait_for(dt);
|
||||||
|
}
|
||||||
|
template<class _Clock, class _Duration>
|
||||||
|
auto wait_until(event_v2::event_t& e, const std::chrono::time_point<_Clock, _Duration>& tp)
|
||||||
|
{
|
||||||
|
return e.wait_until(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
//when_all_for(dt, args...) -> when_all(wait_for(args, dt)...)
|
||||||
|
//就不再单独为每个支持超时的类提供when_all_for实现了。借助when_all和非成员的wait_for实现
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,7 @@ RESUMEF_NS
|
|||||||
|
|
||||||
//为浸入式单向链表提供的next指针
|
//为浸入式单向链表提供的next指针
|
||||||
counted_ptr<state_event_t> _next = nullptr;
|
counted_ptr<state_event_t> _next = nullptr;
|
||||||
|
timer_handler _thandler;
|
||||||
private:
|
private:
|
||||||
//_value引用awaitor保存的值,这样可以尽可能减少创建state的可能。而不必进入没有state就没有value实体被用于返回。
|
//_value引用awaitor保存的值,这样可以尽可能减少创建state的可能。而不必进入没有state就没有value实体被用于返回。
|
||||||
//在调用on_notify()或on_timeout()任意之一后,置为nullptr。
|
//在调用on_notify()或on_timeout()任意之一后,置为nullptr。
|
||||||
@ -191,7 +192,7 @@ RESUMEF_NS
|
|||||||
|
|
||||||
_event->add_wait_list(_state.get());
|
_event->add_wait_list(_state.get());
|
||||||
|
|
||||||
(void)sch->timer()->add(_tp, [_state=_state](bool canceld)
|
_state->_thandler = sch->timer()->add_handler(_tp, [_state=_state](bool canceld)
|
||||||
{
|
{
|
||||||
if (!canceld)
|
if (!canceld)
|
||||||
_state->on_timeout();
|
_state->on_timeout();
|
||||||
|
@ -26,8 +26,11 @@ RESUMEF_NS
|
|||||||
|
|
||||||
void timer_manager::clear()
|
void timer_manager::clear()
|
||||||
{
|
{
|
||||||
|
std::unique_lock<spinlock> __lock(_added_mtx);
|
||||||
auto _atimer = std::move(_added_timers);
|
auto _atimer = std::move(_added_timers);
|
||||||
for (auto & sptr : _atimer)
|
__lock.unlock();
|
||||||
|
|
||||||
|
for (auto& sptr : _atimer)
|
||||||
call_target_(sptr, true);
|
call_target_(sptr, true);
|
||||||
|
|
||||||
auto _rtimer = std::move(_runing_timers);
|
auto _rtimer = std::move(_runing_timers);
|
||||||
@ -39,6 +42,8 @@ RESUMEF_NS
|
|||||||
{
|
{
|
||||||
assert(sptr);
|
assert(sptr);
|
||||||
assert(sptr->st == timer_target::State::Invalid);
|
assert(sptr->st == timer_target::State::Invalid);
|
||||||
|
|
||||||
|
scoped_lock<spinlock> __lock(_added_mtx);
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
assert(sptr->_manager == nullptr);
|
assert(sptr->_manager == nullptr);
|
||||||
sptr->_manager = this;
|
sptr->_manager = this;
|
||||||
@ -64,32 +69,37 @@ RESUMEF_NS
|
|||||||
|
|
||||||
void timer_manager::update()
|
void timer_manager::update()
|
||||||
{
|
{
|
||||||
if (_added_timers.size() > 0)
|
|
||||||
{
|
{
|
||||||
for (auto & sptr : _added_timers)
|
std::unique_lock<spinlock> __lock(_added_mtx);
|
||||||
|
|
||||||
|
if (_added_timers.size() > 0)
|
||||||
{
|
{
|
||||||
if (sptr->st == timer_target::State::Added)
|
auto _atimer = std::move(_added_timers);
|
||||||
|
_added_timers.reserve(128);
|
||||||
|
__lock.unlock();
|
||||||
|
|
||||||
|
for (auto& sptr : _atimer)
|
||||||
{
|
{
|
||||||
sptr->st = timer_target::State::Runing;
|
if (sptr->st == timer_target::State::Added)
|
||||||
_runing_timers.insert({ sptr->tp, sptr });
|
{
|
||||||
}
|
sptr->st = timer_target::State::Runing;
|
||||||
else
|
_runing_timers.insert({ sptr->tp, sptr });
|
||||||
{
|
}
|
||||||
assert(sptr->st == timer_target::State::Invalid);
|
else
|
||||||
call_target_(sptr, true);
|
{
|
||||||
|
assert(sptr->st == timer_target::State::Invalid);
|
||||||
|
call_target_(sptr, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_added_timers.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_runing_timers.size() > 0)
|
if (_runing_timers.size() > 0)
|
||||||
{
|
{
|
||||||
auto now_ = clock_type::now();
|
auto now_ = clock_type::now();
|
||||||
timer_map_type _timers = std::move(_runing_timers);
|
|
||||||
|
|
||||||
auto iter = _timers.begin();
|
auto iter = _runing_timers.begin();
|
||||||
for (; iter != _timers.end(); ++iter)
|
for (; iter != _runing_timers.end(); ++iter)
|
||||||
{
|
{
|
||||||
auto & kv = *iter;
|
auto & kv = *iter;
|
||||||
if (kv.first > now_)
|
if (kv.first > now_)
|
||||||
@ -97,9 +107,8 @@ RESUMEF_NS
|
|||||||
|
|
||||||
call_target_(kv.second, kv.second->st == timer_target::State::Invalid);
|
call_target_(kv.second, kv.second->st == timer_target::State::Invalid);
|
||||||
}
|
}
|
||||||
_timers.erase(_timers.begin(), iter);
|
|
||||||
|
|
||||||
_runing_timers = std::move(_timers);
|
_runing_timers.erase(_runing_timers.begin(), iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -80,6 +80,7 @@ RESUMEF_NS
|
|||||||
typedef std::vector<timer_target_ptr> timer_vector_type;
|
typedef std::vector<timer_target_ptr> timer_vector_type;
|
||||||
typedef std::multimap<clock_type::time_point, timer_target_ptr> timer_map_type;
|
typedef std::multimap<clock_type::time_point, timer_target_ptr> timer_map_type;
|
||||||
protected:
|
protected:
|
||||||
|
spinlock _added_mtx;
|
||||||
timer_vector_type _added_timers;
|
timer_vector_type _added_timers;
|
||||||
public:
|
public:
|
||||||
timer_map_type _runing_timers;
|
timer_map_type _runing_timers;
|
||||||
@ -112,7 +113,7 @@ RESUMEF_NS
|
|||||||
|
|
||||||
inline bool empty() const
|
inline bool empty() const
|
||||||
{
|
{
|
||||||
return _added_timers.empty() && _runing_timers.empty();
|
return _runing_timers.empty() && _added_timers.empty();
|
||||||
}
|
}
|
||||||
void clear();
|
void clear();
|
||||||
void update();
|
void update();
|
||||||
|
Loading…
Reference in New Issue
Block a user