From 5ea36e6cc0ae1ce8759a6f3acacb9267b74b6f8b Mon Sep 17 00:00:00 2001 From: tearshark Date: Tue, 10 Mar 2020 23:38:06 +0800 Subject: [PATCH] =?UTF-8?q?timer=E6=8F=90=E4=BE=9B=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E7=9A=84=E5=8F=AF=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- librf/src/event_v2.cpp | 4 ++++ librf/src/event_v2.h | 14 +++++++++++++ librf/src/event_v2.inl | 3 ++- librf/src/timer.cpp | 45 +++++++++++++++++++++++++----------------- librf/src/timer.h | 3 ++- 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/librf/src/event_v2.cpp b/librf/src/event_v2.cpp index d0b6520..3c09d0b 100644 --- a/librf/src/event_v2.cpp +++ b/librf/src/event_v2.cpp @@ -26,6 +26,8 @@ RESUMEF_NS if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) { *oldValue = false; + _thandler.stop(); + this->_coro = nullptr; } } @@ -36,6 +38,7 @@ RESUMEF_NS if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) { *oldValue = true; + _thandler.stop(); assert(this->_scheduler != nullptr); if (this->_coro) @@ -52,6 +55,7 @@ RESUMEF_NS if (oldValue != nullptr && _value.compare_exchange_strong(oldValue, nullptr, std::memory_order_acq_rel)) { *oldValue = false; + _thandler.reset(); assert(this->_scheduler != nullptr); if (this->_coro) diff --git a/librf/src/event_v2.h b/librf/src/event_v2.h index eed1f76..2819741 100644 --- a/librf/src/event_v2.h +++ b/librf/src/event_v2.h @@ -37,4 +37,18 @@ RESUMEF_NS timeout_awaiter wait_until_(const clock_type::time_point& tp) const noexcept; }; } + + template + auto wait_for(event_v2::event_t& e, const std::chrono::duration<_Rep, _Period>& dt) + { + return e.wait_for(dt); + } + template + 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实现 } diff --git a/librf/src/event_v2.inl b/librf/src/event_v2.inl index a25e051..e5256b6 100644 --- a/librf/src/event_v2.inl +++ b/librf/src/event_v2.inl @@ -91,6 +91,7 @@ RESUMEF_NS //为浸入式单向链表提供的next指针 counted_ptr _next = nullptr; + timer_handler _thandler; private: //_value引用awaitor保存的值,这样可以尽可能减少创建state的可能。而不必进入没有state就没有value实体被用于返回。 //在调用on_notify()或on_timeout()任意之一后,置为nullptr。 @@ -191,7 +192,7 @@ RESUMEF_NS _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) _state->on_timeout(); diff --git a/librf/src/timer.cpp b/librf/src/timer.cpp index 3559153..3724d74 100644 --- a/librf/src/timer.cpp +++ b/librf/src/timer.cpp @@ -26,8 +26,11 @@ RESUMEF_NS void timer_manager::clear() { + std::unique_lock __lock(_added_mtx); auto _atimer = std::move(_added_timers); - for (auto & sptr : _atimer) + __lock.unlock(); + + for (auto& sptr : _atimer) call_target_(sptr, true); auto _rtimer = std::move(_runing_timers); @@ -39,6 +42,8 @@ RESUMEF_NS { assert(sptr); assert(sptr->st == timer_target::State::Invalid); + + scoped_lock __lock(_added_mtx); #if _DEBUG assert(sptr->_manager == nullptr); sptr->_manager = this; @@ -64,32 +69,37 @@ RESUMEF_NS void timer_manager::update() { - if (_added_timers.size() > 0) { - for (auto & sptr : _added_timers) + std::unique_lock __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; - _runing_timers.insert({ sptr->tp, sptr }); - } - else - { - 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) { 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; if (kv.first > now_) @@ -97,9 +107,8 @@ RESUMEF_NS 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); } } } \ No newline at end of file diff --git a/librf/src/timer.h b/librf/src/timer.h index 0cfbc30..c32ff8f 100644 --- a/librf/src/timer.h +++ b/librf/src/timer.h @@ -80,6 +80,7 @@ RESUMEF_NS typedef std::vector timer_vector_type; typedef std::multimap timer_map_type; protected: + spinlock _added_mtx; timer_vector_type _added_timers; public: timer_map_type _runing_timers; @@ -112,7 +113,7 @@ RESUMEF_NS inline bool empty() const { - return _added_timers.empty() && _runing_timers.empty(); + return _runing_timers.empty() && _added_timers.empty(); } void clear(); void update();