34GNet::TimerList::Value::Value()
38GNet::TimerList::Value::Value( TimerBase * t , ExceptionSink es ) :
44inline bool GNet::TimerList::Value::operator==(
const Value & v )
const noexcept
46 return m_timer == v.m_timer ;
49inline void GNet::TimerList::Value::resetIf( TimerBase * p )
noexcept
55void GNet::TimerList::Value::disarmIf( ExceptionHandler * eh )
noexcept
63GNet::TimerList::Lock::Lock( TimerList & timer_list ) :
64 m_timer_list(timer_list)
69GNet::TimerList::Lock::~Lock()
71 m_timer_list.unlock() ;
80 if( m_this ==
nullptr )
92 (m_locked?m_list_added:m_list).push_back( Value(&t,es) ) ;
98 removeFrom( m_list , &timer ) ;
99 removeFrom( m_list_added , &timer ) ;
100 if( m_soonest == &timer ) m_soonest = nullptr ;
103void GNet::TimerList::removeFrom( List & list ,
TimerBase * timer_p )
noexcept
105 for(
auto & value : list )
106 value.resetIf( timer_p ) ;
111 disarmIn( m_list , eh ) ;
112 disarmIn( m_list_added , eh ) ;
115void GNet::TimerList::disarmIn( List & list ,
ExceptionHandler * eh )
noexcept
117 for(
auto & value : list )
118 value.disarmIf( eh ) ;
124 timer.
adjust( m_adjust++ ) ;
126 if( m_soonest == &timer )
127 m_soonest = nullptr ;
129 if( m_soonest !=
nullptr && timer.
tref() < m_soonest->tref() )
135 G_ASSERT( !timer.
active() ) ;
136 if( m_soonest == &timer )
137 m_soonest = nullptr ;
142 G_ASSERT( !m_locked ) ;
144 for(
const auto & t : m_list )
146 if( t.m_timer !=
nullptr && t.m_timer->active() && ( result ==
nullptr || t.m_timer->tref() < result->
tref() ) )
154 if( m_soonest ==
nullptr )
155 m_soonest = findSoonest() ;
157 if( m_soonest ==
nullptr )
161 else if( m_soonest->immediate() )
181 return m_this != nullptr ;
187 if( m_this ==
nullptr )
192void GNet::TimerList::lock()
197void GNet::TimerList::unlock()
207void GNet::TimerList::mergeAdded()
209 if( !m_list_added.empty() )
211 m_list.reserve( m_list.size() + m_list_added.size() ) ;
212 m_list.insert( m_list.end() , m_list_added.begin() , m_list_added.end() ) ;
213 m_list_added.clear() ;
217void GNet::TimerList::purgeRemoved()
222 m_list.erase( std::remove( m_list.begin() , m_list.end() , Value(
nullptr,{}) ) , m_list.end() ) ;
228 G_ASSERT( m_list_added.empty() ) ;
233 auto expired_end = std::partition( m_list.begin() , m_list.end() ,
234 [&now](
const Value &value){ return value.m_timer != nullptr && value.m_timer->active() && value.m_timer->expired(now) ; } ) ;
236 std::sort( m_list.begin() , expired_end ,
237 [](
const Value &a,
const Value &b){ return a.m_timer->tref() < b.m_timer->tref() ; } ) ;
239 if( expired_end != m_list.begin() )
240 m_soonest = nullptr ;
242 for( List::iterator value_p = m_list.begin() ; value_p != expired_end ; ++value_p )
244 if( value_p->m_timer !=
nullptr && value_p->m_timer->active() && value_p->m_timer->expired(now) )
245 doTimeout( *value_p ) ;
251void GNet::TimerList::doTimeout( Value & value )
257 value.m_timer->doTimeout() ;
261 if( value.m_es.set() )
262 value.m_es.call( e ,
true ) ;
266 catch( std::exception & e )
268 if( value.m_es.set() )
269 value.m_es.call( e ,
false ) ;
An exception class that is detected by GNet::EventHandlerList and results in onException() being call...
A class that sets the G::LogOuput::context() while in scope.
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket/future event...
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
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.
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.
void add(TimerBase &, ExceptionSink)
Adds a timer. Called from the Timer constructor.
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().