X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FClockService.cc;h=d9733d8e8d67527df34df478c9ad695f9b3a597e;hb=a634d4df375e12f0a9dcd0014f1ee14b70de16b8;hp=f31ec4f447e663da62c273e82d06908b4c04dda3;hpb=ffa36b2d409289a2f3f0de46667aa2bf558f393f;p=senf.git diff --git a/Scheduler/ClockService.cc b/Scheduler/ClockService.cc index f31ec4f..d9733d8 100644 --- a/Scheduler/ClockService.cc +++ b/Scheduler/ClockService.cc @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -31,134 +31,12 @@ #include #include #include -#include "Utils/Exception.hh" +#include "../Utils/Exception.hh" //#include "ClockService.mpp" #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(); - - 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"