Browse Source

timer提供线程安全的可能

tags/v2.9.7
tearshark 4 years ago
parent
commit
5ea36e6cc0
5 changed files with 49 additions and 20 deletions
  1. 4
    0
      librf/src/event_v2.cpp
  2. 14
    0
      librf/src/event_v2.h
  3. 2
    1
      librf/src/event_v2.inl
  4. 27
    18
      librf/src/timer.cpp
  5. 2
    1
      librf/src/timer.h

+ 4
- 0
librf/src/event_v2.cpp View File

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;
} }
} }
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)
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)

+ 14
- 0
librf/src/event_v2.h View File

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实现
} }

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

//为浸入式单向链表提供的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。
_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();

+ 27
- 18
librf/src/timer.cpp View File

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);
{ {
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;
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)
{
sptr->st = timer_target::State::Runing;
_runing_timers.insert({ sptr->tp, sptr });
}
else
auto _atimer = std::move(_added_timers);
_added_timers.reserve(128);
__lock.unlock();
for (auto& sptr : _atimer)
{ {
assert(sptr->st == timer_target::State::Invalid);
call_target_(sptr, true);
if (sptr->st == timer_target::State::Added)
{
sptr->st = timer_target::State::Runing;
_runing_timers.insert({ sptr->tp, sptr });
}
else
{
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();
for (; iter != _timers.end(); ++iter)
auto iter = _runing_timers.begin();
for (; iter != _runing_timers.end(); ++iter)
{ {
auto & kv = *iter; auto & kv = *iter;
if (kv.first > now_) if (kv.first > now_)
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);
} }
} }
} }

+ 2
- 1
librf/src/timer.h View File

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;
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…
Cancel
Save