33GNet::TimerList::ListItem::ListItem( TimerBase * t , EventState es ) :
40inline bool GNet::TimerList::ListItem::operator==(
const ListItem & rhs )
const noexcept
42 return m_timer == rhs.m_timer ;
46inline void GNet::TimerList::ListItem::resetIf( TimerBase * p )
noexcept
52void GNet::TimerList::ListItem::disarmIf( ExceptionHandler * eh )
noexcept
60GNet::TimerList::Lock::Lock( TimerList & timer_list ) :
61 m_timer_list(timer_list)
66GNet::TimerList::Lock::~Lock()
68 m_timer_list.unlock() ;
77 if( m_this ==
nullptr )
89 (m_locked?m_list_added:m_list).emplace_back( &t , es ) ;
95 removeFrom( m_list , &timer ) ;
96 removeFrom( m_list_added , &timer ) ;
97 if( m_soonest == &timer ) m_soonest = nullptr ;
100void GNet::TimerList::removeFrom( List & list ,
TimerBase * timer_p )
noexcept
102 for(
auto & list_item : list )
103 list_item.resetIf( timer_p ) ;
108 disarmIn( m_list , eh ) ;
109 disarmIn( m_list_added , eh ) ;
112void GNet::TimerList::disarmIn( List & list ,
ExceptionHandler * eh )
noexcept
114 for(
auto & list_item : list )
115 list_item.disarmIf( eh ) ;
121 timer.
adjust( m_adjust++ ) ;
123 if( m_soonest == &timer )
124 m_soonest = nullptr ;
126 if( m_soonest !=
nullptr && timer.
tref() < m_soonest->tref() )
132 G_ASSERT( !timer.
active() ) ;
133 if( m_soonest == &timer )
134 m_soonest = nullptr ;
139 G_ASSERT( !m_locked ) ;
141 for(
const auto & t : m_list )
143 if( t.m_timer !=
nullptr && t.m_timer->active() && ( result ==
nullptr || t.m_timer->tref() < result->
tref() ) )
151 if( m_soonest ==
nullptr )
152 m_soonest = findSoonest() ;
154 if( m_soonest ==
nullptr )
158 else if( m_soonest->immediate() )
178 return m_this != nullptr ;
184 if( m_this ==
nullptr )
189void GNet::TimerList::lock()
194void GNet::TimerList::unlock()
204void GNet::TimerList::mergeAdded()
206 if( !m_list_added.empty() )
208 if( m_soonest !=
nullptr && (m_list.size()+m_list_added.size()) > m_list.capacity() )
209 m_soonest = nullptr ;
210 m_list.reserve( m_list.size() + m_list_added.size() ) ;
211 m_list.insert( m_list.end() , m_list_added.begin() , m_list_added.end() ) ;
212 m_list_added.clear() ;
216void GNet::TimerList::purgeRemoved()
221 m_soonest = nullptr ;
222 m_list.erase( std::remove_if( m_list.begin() , m_list.end() ,
223 [](
const ListItem &v_){ return v_.m_timer == nullptr ; } ) , m_list.end() ) ;
229 G_ASSERT( m_list_added.empty() ) ;
235 auto expired_end = std::partition( m_list.begin() , m_list.end() ,
236 [&now](
const ListItem &li_){ return li_.m_timer != nullptr && li_.m_timer->active() && li_.m_timer->expired(now) ; } ) ;
239 std::sort( m_list.begin() , expired_end ,
240 [](
const ListItem &a,
const ListItem &b){ return a.m_timer->tref() < b.m_timer->tref() ; } ) ;
243 if( expired_end != m_list.begin() )
244 m_soonest = nullptr ;
247 for( List::iterator item_p = m_list.begin() ; item_p != expired_end ; ++item_p )
250 if( item_p->m_timer !=
nullptr && item_p->m_timer->active() && item_p->m_timer->expired(now) )
251 doTimeout( *item_p ) ;
258void GNet::TimerList::doTimeout( ListItem & item )
264 item.m_timer->doTimeout() ;
268 if( item.m_es.hasExceptionHandler() )
269 item.m_es.doOnException( e ,
true ) ;
273 catch( std::exception & e )
275 if( item.m_es.hasExceptionHandler() )
276 item.m_es.doOnException( e ,
false ) ;
An exception class that is caught separately by GNet::EventEmitter and GNet::TimerList so that onExce...
A class that sets the G::LogOuput::context() while in scope.
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket/future event...
An interface used by GNet::TimerList to keep track of pending timeouts and to deliver timeout events.
void adjust(unsigned long)
Used by TimerList to set the order of immedate() timer expiry.
bool immediate() const
Used by TimerList.
const G::TimerTime & tref() const noexcept
An inline noexcept alternative to t().
bool active() const noexcept
Returns true if the timer is started and not cancelled.
A singleton which maintains a list of all Timer objects, and interfaces to the event loop on their be...
std::pair< G::TimeInterval, bool > interval() const
Returns the interval to the first timer expiry.
void remove(TimerBase &) noexcept
Removes a timer from the list.
void doTimeouts()
Triggers the timeout callbacks of any expired timers.
static bool exists()
Returns true if instance() exists.
void disarm(ExceptionHandler *) noexcept
Resets any matching ExceptionHandler pointers.
void updateOnStart(TimerBase &)
Called by Timer when a timer is started.
void add(TimerBase &, EventState)
Adds a timer. Called from the Timer constructor.
static TimerList & instance()
Singleton access. Throws an exception if none.
static TimerList * ptr() noexcept
Singleton access. Returns nullptr if none.
TimerList()
Default constructor.
void updateOnCancel(TimerBase &)
Called by Timer when a timer is cancelled.
An interval between two G::SystemTime values or two G::TimerTime values.
A monotonically increasing subsecond-resolution timestamp, notionally unrelated to time_t.
static TimerTime now()
Factory function for the current steady-clock time.
static TimerTime zero()
Factory function for the start of the epoch, guaranteed to be less than any now().