#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-#define CheckError(op,args) if (op args < 0) throw SystemException(# op, errno)
-
-///////////////////////////////////////////////////////////////////////////
-// senf::ClockService::Impl
-
-struct senf::ClockService::Impl
-{
- Impl();
-
- void block();
- void unblock();
-
- /// Internal: temporarily block signals (RAII idiom)
- struct Blocker {
- Blocker(Impl * i) : impl(i) { impl->block(); }
- ~Blocker() { impl->unblock(); }
- Impl * impl;
- };
-
- static void timer(int);
-
- struct sigaction oldaction;
- struct itimerval olditimer;
- sigset_t alrm_set;
-};
-
-prefix_ senf::ClockService::Impl::Impl()
-{
- CheckError( sigemptyset, (&alrm_set) );
- CheckError( sigaddset, (&alrm_set, SIGALRM) );
-}
-
-prefix_ void senf::ClockService::Impl::block()
-{
- CheckError( sigprocmask, (SIG_BLOCK, &alrm_set, 0) );
-}
-
-prefix_ void senf::ClockService::Impl::unblock()
-{
- CheckError( sigprocmask, (SIG_UNBLOCK, &alrm_set, 0) );
-}
-
-prefix_ void senf::ClockService::Impl::timer(int)
-{
- ClockService::instance().timer();
-}
-
-///////////////////////////////////////////////////////////////////////////
-// senf::ClockService
-
-prefix_ senf::ClockService::~ClockService()
-{
- setitimer(ITIMER_REAL, &impl_->olditimer, 0);
- sigaction(SIGALRM, &impl_->oldaction, 0);
-}
-
-////////////////////////////////////////
-// private members
-
-prefix_ senf::ClockService::ClockService()
- : impl_(new ClockService::Impl())
-{
- restart_m(false);
-}
-
-prefix_ void senf::ClockService::timer()
-{
- boost::posix_time::ptime time (boost::posix_time::microsec_clock::universal_time());
- if (checkSkew(time))
- clockSkew(time, heartbeat_ + boost::posix_time::seconds(
- ClockService::CheckInterval));
- heartbeat_ = time;
-}
-
-prefix_ void senf::ClockService::restart_m(bool restart)
-{
- if (restart)
- // if any syscall fails, the alarm signal stays blocked which is correct
- impl_->block();
-
- base_ = boost::posix_time::microsec_clock::universal_time();
- heartbeat_ = base_;
-
- struct sigaction action;
- action.sa_handler = & senf::ClockService::Impl::timer;
- CheckError( sigemptyset, (&action.sa_mask) );
- action.sa_flags = SA_RESTART;
- CheckError( sigaction, (SIGALRM, &action, restart ? 0 : &impl_->oldaction) );
-
- restartTimer(restart);
-
- impl_->unblock();
-}
-
-prefix_ void senf::ClockService::restartTimer(bool restart)
-{
- struct itimerval itimer;
- itimer.it_interval.tv_sec = CheckInterval;
- itimer.it_interval.tv_usec = 0;
- itimer.it_value.tv_sec = CheckInterval;
- itimer.it_value.tv_usec = 0;
- CheckError( setitimer, (ITIMER_REAL, &itimer, restart ? 0 : &impl_->olditimer) );
-}
-
-prefix_ void senf::ClockService::updateSkew(boost::posix_time::ptime time)
-{
- Impl::Blocker alrmBlocker (impl_.get());
-
- // Make a second 'checkSkew' test, this time with SIGALRM blocked. See
- // senf::ClockService::now_i()
-
- if (checkSkew(time)) {
- struct itimerval itimer;
- CheckError( getitimer, (ITIMER_REAL, &itimer) );
- clockSkew(time, (heartbeat_
- + boost::posix_time::seconds(CheckInterval)
- - boost::posix_time::seconds(itimer.it_value.tv_sec)
- - boost::posix_time::microseconds(itimer.it_value.tv_usec)));
- heartbeat_ = time;
- restartTimer();
- }
-}
-
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "ClockService.mpp"