we observed some issues within our software due to time modifications (I must think of the famous Rocky Horror Picture Show whenever I make the Time Warp within our simulator ). I found and fixed some locations and I stumbled over the following code sniplets :
(Platform.cpp from RCF 2.0.1.100, also included in older versions)
Code: Select all
// TODO: any issues with monotonicity of gettimeofday()? <--- Yes !
boost::uint32_t getCurrentTimeMs()
{
static struct timeval start = {0};
static bool init = false;
if (!init)
{
init = true;
gettimeofday(&start, NULL);
}
struct timeval now;
gettimeofday(&now, NULL);
long seconds = now.tv_sec - start.tv_sec;
long microseconds = now.tv_usec - start.tv_usec;
boost::uint64_t timeMs = boost::uint64_t(seconds)*1000 + microseconds/1000;
timeMs = timeMs & 0xFFFFFFFF;
return static_cast<boost::uint32_t>(timeMs) - OffsetMs;
}
(SessionTimeoutService.cpp from RCF 2.0.1.100, also included in older versions)
Code: Select all
void SessionTimeoutService::onTimer()
{
mSessionsTemp.resize(0);
mpRcfServer->enumerateSessions(std::back_inserter(mSessionsTemp));
for (std::size_t i=0; i<mSessionsTemp.size(); ++i)
{
SessionStatePtr sessionStatePtr = mSessionsTemp[i].lock();
if (sessionStatePtr)
{
RcfSessionPtr rcfSessionPtr = sessionStatePtr->getSessionPtr();
if (rcfSessionPtr)
{
boost::uint32_t lastTouched = rcfSessionPtr->getTouchTimestamp();
if (lastTouched)
{
RCF::Timer lastTouchedTimer( lastTouched );
if (lastTouchedTimer.elapsed(mSessionTimeoutMs))
{
rcfSessionPtr->disconnect();
}
}
}
}
}
}
(include/RCF/thread/posix_event.hpp and include/RCF/thread/impl/posix_event.ipp from RCF 2.0.1.100, also included in older versions)
Code: Select all
posix_event::posix_event()
{
>>
+ ::pthread_condattr_init(&condattr_);
+ ::pthread_condattr_setclock(&condattr_, CLOCK_MONOTONIC);
>>
int error = ::pthread_cond_init(&cond_, 0);
RCF_VERIFY(error == 0, Exception(_RcfError_ThreadingError("pthread_cond_init()"), error));
}
template <typename Lock>
bool timed_wait(Lock& lock, boost::uint32_t waitMs)
{
BOOST_ASSERT(lock.locked());
>>
+ struct timespec ts = {0};
+ clock_gettime(CLOCK_MONOTONIC, &ts);
>>
// Add waitMs to current time.
ts.tv_sec += (waitMs / 1000);
boost::uint32_t remainderMs = waitMs % 1000;
ts.tv_nsec += (remainderMs * 1000 * 1000);
// Check for overflow in tv_nsec.
if (ts.tv_nsec >= 1000*1000*1000)
{
BOOST_ASSERT(ts.tv_nsec < 2*1000*1000*1000);
ts.tv_sec += 1;
ts.tv_nsec -= 1000*1000*1000;
}
// POSIX automatically unlocks and locks the mutex.
int ret = ::pthread_cond_timedwait(&cond_, &lock.mutex().mutex_, &ts); // Ignore EINVAL.
if (ret == ETIMEDOUT)
{
return false;
}
return true;
}
Kind Regards,
Volker