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

This patch happened in upstream csocket too, so update won't break
anything.
This commit is contained in:
Alexey Sokolov
2012-03-20 08:49:59 +07:00
parent 27bebf1ca4
commit 3aa6b581fc
3 changed files with 80 additions and 39 deletions
+10 -8
View File
@@ -362,16 +362,18 @@ public:
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 @@ public:
//! 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 @@ public:
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 @@ protected:
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 @@ private:
*/
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 );
+68 -30
View File
@@ -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 )
{
time_t iNextRunTime = iNow + iMaxResolution;
if( timercmp( &min, &another, > ) )
{
min = another;
}
}
timeval CSocketManager::GetDynamicSleepTime( const timeval& tNow, const timeval& tMaxResolution ) const
{
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 )
+2 -1
View File
@@ -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());
}