Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Csock: able use non-int number of secs for timer.

This patch happened in upstream csocket too, so update won't break
anything.
  • Loading branch information...
commit 3aa6b581fc4a2d8c616ae0137932633c659a4f7d 1 parent 27bebf1
Alexey Sokolov DarthGandalf authored
Showing with 80 additions and 39 deletions.
  1. +10 −8 include/znc/Csocket.h
  2. +68 −30 src/Csocket.cpp
  3. +2 −1  src/Modules.cpp
18 include/znc/Csocket.h
View
@@ -362,16 +362,18 @@ class CCron
virtual ~CCron() {}
//! This is used by the Job Manager, and not you directly
- void run( time_t & iNow );
+ void run( timeval & tNow );
/**
* @param TimeSequence how often to run in seconds
* @param iMaxCycles how many times to run, 0 makes it run forever
*/
- void StartMaxCycles( int TimeSequence, u_int iMaxCycles );
+ void StartMaxCycles( double fTimeSequence, u_int iMaxCycles );
+ void StartMaxCycles( const timeval& tTimeSequence, u_int iMaxCycles );
//! starts and runs infinity amount of times
- void Start( int TimeSequence );
+ void Start( double fTimeSequence );
+ void Start( const timeval& TimeSequence );
//! call this to turn off your cron, it will be removed
void Stop();
@@ -382,7 +384,7 @@ class CCron
//! removes the pause on RunJon
void UnPause();
- int GetInterval() const;
+ timeval GetInterval() const;
u_int GetMaxCycles() const;
u_int GetCyclesLeft() const;
@@ -393,7 +395,7 @@ class CCron
void SetName( const CS_STRING & sName );
//! returns the timestamp of the next estimated run time. Note that it may not run at this EXACT time, but it will run at least at this time or after
- time_t GetNextRun() const { return( m_iTime ); }
+ timeval GetNextRun() const { return( m_tTime ); }
public:
@@ -404,9 +406,9 @@ class CCron
bool m_bRunOnNextCall; //!< if set to true, RunJob() gets called on next invocation of run() despite the timeout
private:
- time_t m_iTime;
+ timeval m_tTime;
bool m_bActive, m_bPause;
- int m_iTimeSequence;
+ timeval m_tTimeSequence;
u_int m_iMaxCycles, m_iCycles;
CS_STRING m_sName;
};
@@ -1494,7 +1496,7 @@ class CSocketManager : public std::vector<Csock *>, public CSockCommon
*/
void Select( std::map<Csock *, EMessages> & mpeSocks );
- time_t GetDynamicSleepTime( time_t iNow, time_t iMaxResolution = 3600 ) const;
+ timeval GetDynamicSleepTime( const timeval& tNow, const timeval& tMaxResolution ) const;
//! internal use only
virtual void SelectSock( std::map<Csock *, EMessages> & mpeSocks, EMessages eErrno, Csock * pcSock );
98 src/Csocket.cpp
View
@@ -627,21 +627,22 @@ CCron::CCron()
m_iCycles = 0;
m_iMaxCycles = 0;
m_bActive = true;
- m_iTime = 0;
- m_iTimeSequence = 60;
+ timerclear( &m_tTime );
+ m_tTimeSequence.tv_sec = 60;
+ m_tTimeSequence.tv_usec = 0;
m_bPause = false;
m_bRunOnNextCall = false;
}
-void CCron::run( time_t & iNow )
+void CCron::run( timeval & tNow )
{
if( m_bPause )
return;
- if( iNow == 0 )
- iNow = time( NULL );
+ if( !timerisset( &tNow ) )
+ gettimeofday( &tNow, NULL );
- if(( m_bActive ) && ( iNow >= m_iTime || m_bRunOnNextCall ) )
+ if(( m_bActive ) && ( !timercmp( &tNow, &m_tTime, < ) || m_bRunOnNextCall ) )
{
m_bRunOnNextCall = false; // Setting this here because RunJob() could set it back to true
RunJob();
@@ -649,22 +650,37 @@ void CCron::run( time_t & iNow )
if(( m_iMaxCycles > 0 ) && ( ++m_iCycles >= m_iMaxCycles ) )
m_bActive = false;
else
- m_iTime = iNow + m_iTimeSequence;
+ timeradd( &tNow, &m_tTimeSequence, &m_tTime );
}
}
-void CCron::StartMaxCycles( int TimeSequence, u_int iMaxCycles )
+void CCron::StartMaxCycles( double fTimeSequence, u_int iMaxCycles )
{
- m_iTimeSequence = TimeSequence;
- m_iTime = time( NULL ) + m_iTimeSequence;
+ timeval tNow;
+ m_tTimeSequence.tv_sec = (time_t) fTimeSequence;
+ m_tTimeSequence.tv_usec = (suseconds_t) ((fTimeSequence - (time_t) fTimeSequence) * 1000000);
+ gettimeofday( &tNow, NULL );
+ timeradd( &tNow, &m_tTimeSequence, &m_tTime );
m_iMaxCycles = iMaxCycles;
}
-void CCron::Start( int TimeSequence )
+void CCron::StartMaxCycles( const timeval& tTimeSequence, u_int iMaxCycles )
{
- m_iTimeSequence = TimeSequence;
- m_iTime = time( NULL ) + m_iTimeSequence;
- m_iMaxCycles = 0;
+ timeval tNow;
+ m_tTimeSequence = tTimeSequence;
+ gettimeofday( &tNow, NULL );
+ timeradd( &tNow, &m_tTimeSequence, &m_tTime );
+ m_iMaxCycles = iMaxCycles;
+}
+
+void CCron::Start( double fTimeSequence )
+{
+ StartMaxCycles( fTimeSequence, 0 );
+}
+
+void CCron::Start( const timeval& tTimeSequence )
+{
+ StartMaxCycles( tTimeSequence, 0 );
}
void CCron::Stop()
@@ -682,7 +698,7 @@ void CCron::UnPause()
m_bPause = false;
}
-int CCron::GetInterval() const { return( m_iTimeSequence ); }
+timeval CCron::GetInterval() const { return( m_tTimeSequence ); }
u_int CCron::GetMaxCycles() const { return( m_iMaxCycles ); }
u_int CCron::GetCyclesLeft() const { return(( m_iMaxCycles > m_iCycles ? ( m_iMaxCycles - m_iCycles ) : 0 ) ); }
@@ -765,7 +781,8 @@ void CSockCommon::AssignFDs( std::map< int, short > & miiReadyFds, struct timeva
void CSockCommon::Cron()
{
- time_t iNow = 0;
+ timeval tNow;
+ timerclear( &tNow );
for( vector<CCron *>::size_type a = 0; a < m_vcCrons.size(); a++ )
{
@@ -777,7 +794,7 @@ void CSockCommon::Cron()
m_vcCrons.erase( m_vcCrons.begin() + a-- );
}
else
- pcCron->run( iNow );
+ pcCron->run( tNow );
}
}
@@ -2893,9 +2910,13 @@ void CSocketManager::DynamicSelectLoop( u_long iLowerBounds, u_long iUpperBounds
if( m_errno == SELECT_TIMEOUT )
{
// only do this if the previous call to select was a timeout
- time_t iNow = time( NULL );
- u_long iSelectTimeout = GetDynamicSleepTime( iNow, iMaxResolution );
- iSelectTimeout *= 1000000;
+ timeval tMaxResolution;
+ timeval tNow;
+ tMaxResolution.tv_sec = iMaxResolution;
+ tMaxResolution.tv_usec = 0;
+ gettimeofday( &tNow, NULL );
+ timeval tSelectTimeout = GetDynamicSleepTime( tNow, tMaxResolution );
+ u_long iSelectTimeout = tSelectTimeout.tv_sec * 1000000 + tSelectTimeout.tv_usec;
iSelectTimeout = std::max( iLowerBounds, iSelectTimeout );
iSelectTimeout = std::min( iSelectTimeout, iUpperBounds );
if( iLowerBounds != iSelectTimeout )
@@ -3478,9 +3499,18 @@ void CSocketManager::Select( std::map<Csock *, EMessages> & mpeSocks )
}
}
-time_t CSocketManager::GetDynamicSleepTime( time_t iNow, time_t iMaxResolution ) const
+inline void MinimizeTime( timeval& min, const timeval& another )
+{
+ if( timercmp( &min, &another, > ) )
+ {
+ min = another;
+ }
+}
+
+timeval CSocketManager::GetDynamicSleepTime( const timeval& tNow, const timeval& tMaxResolution ) const
{
- time_t iNextRunTime = iNow + iMaxResolution;
+ timeval tNextRunTime;
+ timeradd( &tNow, &tMaxResolution, &tNextRunTime );
std::vector<Csock *>::const_iterator it;
// This is safe, because we don't modify the vector.
std::vector<Csock *>::const_iterator it_end = this->end();
@@ -3490,29 +3520,37 @@ time_t CSocketManager::GetDynamicSleepTime( time_t iNow, time_t iMaxResolution )
Csock* pSock = *it;
if( pSock->GetConState() != Csock::CST_OK )
- iNextRunTime = iNow; // this is in a nebulous state, need to let it proceed like normal
+ tNextRunTime = tNow; // this is in a nebulous state, need to let it proceed like normal
time_t iTimeoutInSeconds = pSock->GetTimeout();
if( iTimeoutInSeconds > 0 )
{
- time_t iNextTimeout = pSock->GetNextCheckTimeout( iNow );
- iNextRunTime = std::min( iNextRunTime, iNextTimeout );
+ timeval tNextTimeout;
+ tNextTimeout.tv_sec = pSock->GetNextCheckTimeout( 0 ); // TODO convert socket timeouts to timeval too?
+ tNextTimeout.tv_usec = 0;
+ MinimizeTime( tNextRunTime, tNextTimeout );
}
const std::vector<CCron *> & vCrons = pSock->GetCrons();
std::vector<CCron *>::const_iterator cit;
std::vector<CCron *>::const_iterator cit_end = vCrons.end();
for( cit = vCrons.begin(); cit != cit_end; cit++ )
- iNextRunTime = std::min( iNextRunTime, ( *cit )->GetNextRun() );
+ MinimizeTime( tNextRunTime, ( *cit )->GetNextRun() );
}
std::vector<CCron *>::const_iterator cit;
std::vector<CCron *>::const_iterator cit_end = m_vcCrons.end();
for( cit = m_vcCrons.begin(); cit != cit_end; cit++ )
- iNextRunTime = std::min( iNextRunTime, ( *cit )->GetNextRun() );
+ MinimizeTime( tNextRunTime, ( *cit )->GetNextRun() );
- if( iNextRunTime < iNow )
- return( 0 ); // smallest unit possible
- return( std::min( iNextRunTime - iNow, iMaxResolution ) );
+ timeval tReturnValue;
+ if( timercmp( &tNextRunTime, &tNow, < ) )
+ {
+ timerclear( &tReturnValue );
+ return( tReturnValue ); // smallest unit possible
+ }
+ timersub( &tNextRunTime, &tNow, &tReturnValue );
+ MinimizeTime( tReturnValue, tMaxResolution );
+ return( tReturnValue );
}
void CSocketManager::SelectSock( std::map<Csock *, EMessages> & mpeSocks, EMessages eErrno, Csock * pcSock )
3  src/Modules.cpp
View
@@ -303,10 +303,11 @@ void CModule::ListTimers() {
for (it = m_sTimers.begin(); it != m_sTimers.end(); ++it) {
CTimer* pTimer = *it;
unsigned int uCycles = pTimer->GetCyclesLeft();
+ timeval Interval = pTimer->GetInterval();
Table.AddRow();
Table.SetCell("Name", pTimer->GetName());
- Table.SetCell("Secs", CString(pTimer->GetInterval()));
+ Table.SetCell("Secs", CString(Interval.tv_sec) + "seconds" + (Interval.tv_usec ? " " + CString(Interval.tv_usec) + " microseconds" : ""));
Table.SetCell("Cycles", ((uCycles) ? CString(uCycles) : "INF"));
Table.SetCell("Description", pTimer->GetDescription());
}
Please sign in to comment.
Something went wrong with that request. Please try again.