Scheduler: Factor out TimerSource from TimerDispatcher and implement POSIXTimerSource
g0dil [Wed, 28 Jan 2009 17:31:46 +0000 (17:31 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1089 270642c3-0616-0410-b53a-bc976706d245

Packets/80211Bundle/RadiotapPacket.hh
Scheduler/Scheduler.cc
Scheduler/TimerEvent.cc
Scheduler/TimerEvent.cci
Scheduler/TimerEvent.ih
Scheduler/TimerEvent.test.cc
Scheduler/TimerSource.cc [new file with mode: 0644]
Scheduler/TimerSource.cci [new file with mode: 0644]
Scheduler/TimerSource.hh [new file with mode: 0644]

index 5ddec01..178556b 100644 (file)
@@ -155,7 +155,7 @@ namespace senf
         OPTIONAL_FIELD        ( flags,                    RadiotapPacketParser_Flags          ); //<pkgdraw: size=8
         OPTIONAL_FIELD        ( rate,                     UInt8Parser                         );
         SKIP_OPTIONAL_PADDING ( channelOptionsPresent(),  rate, 2                             );
-        OPTIONAL_FIELD        ( channelOptions,           RadiotapPacketParser_ChannelOptions ); //<pkgdraw: size=16
+        OPTIONAL_FIELD        ( channelOptions,           RadiotapPacketParser_ChannelOptions ); //<pkgdraw: size=32
         SKIP_OPTIONAL_PADDING ( fhssPresent(),            channelOptions, 2                   );
         OPTIONAL_FIELD        ( fhss,                     UInt16LSBParser                     );
         OPTIONAL_FIELD        ( dbmAntennaSignal,         Int8Parser                          );
index 2467459..3203d20 100644 (file)
@@ -58,12 +58,12 @@ namespace {
             {
                 senf::scheduler::detail::FIFORunner::instance().startWatchdog();
                 senf::scheduler::detail::SignalDispatcher::instance().unblockSignals();
-                senf::scheduler::detail::TimerDispatcher::instance().unblockSignals();
+                senf::scheduler::detail::TimerDispatcher::instance().enable();
             }
 
         ~SchedulerScopedInit()
             {
-                senf::scheduler::detail::TimerDispatcher::instance().blockSignals();
+                senf::scheduler::detail::TimerDispatcher::instance().disable();
                 senf::scheduler::detail::SignalDispatcher::instance().blockSignals();
                 senf::scheduler::detail::FIFORunner::instance().stopWatchdog();
             }
@@ -74,13 +74,16 @@ prefix_ void senf::scheduler::process()
 {
     SchedulerScopedInit initScheduler;
     terminate_ = false;
+    detail::TimerDispatcher::instance().reschedule();
     while(! terminate_ && ! (detail::FdDispatcher::instance().empty() &&
                              detail::TimerDispatcher::instance().empty() &&
                              detail::FileDispatcher::instance().empty())) {
         detail::FdManager::instance().processOnce();
         detail::FileDispatcher::instance().prepareRun();
         detail::EventHookDispatcher::instance().prepareRun();
+        detail::TimerDispatcher::instance().prepareRun();
         detail::FIFORunner::instance().run();
+        detail::TimerDispatcher::instance().reschedule();
     }
 }
 
index f3113e4..38ad03a 100644 (file)
 ///////////////////////////////cc.p////////////////////////////////////////
 
 prefix_ senf::scheduler::detail::TimerDispatcher::TimerDispatcher()
-    : blocked_ (true)
-{
-    if (pipe(timerPipe_) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("pipe()");
-    senf::scheduler::detail::FdManager::instance().set(timerPipe_[0], detail::FdManager::EV_READ, this);
-
-    sigemptyset(&sigSet_);
-    sigaddset(&sigSet_, SIGALRM);
-    sigprocmask(SIG_BLOCK, &sigSet_, 0);
-
-    struct sigaction act;
-    act.sa_sigaction = &sigHandler;
-    act.sa_mask = sigSet_;
-    act.sa_flags = SA_SIGINFO | SA_RESTART;
-    if (sigaction(SIGALRM, &act, 0) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("sigaction()");
-
-    struct sigevent ev;
-    ::memset(&ev, 0, sizeof(ev));
-    ev.sigev_notify = SIGEV_SIGNAL;
-    ev.sigev_signo = SIGALRM;
-    ev.sigev_value.sival_ptr = this;
-    if (timer_create(CLOCK_MONOTONIC, &ev, &timerId_) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("timer_create()");
-}
+    : source_ (new POSIXTimerSource())
+{}
 
 prefix_ senf::scheduler::detail::TimerDispatcher::~TimerDispatcher()
 {
@@ -66,21 +43,12 @@ prefix_ senf::scheduler::detail::TimerDispatcher::~TimerDispatcher()
     TimerSet::iterator const i_end (timers_.end());
     for (; i != i_end; ++i)
         senf::scheduler::detail::FIFORunner::instance().dequeue(&(*i));
-
-    timer_delete(timerId_);
-    ::signal(SIGALRM, SIG_IGN);
-    sigprocmask(SIG_UNBLOCK, &sigSet_, 0);
-    senf::scheduler::detail::FdManager::instance().remove(timerPipe_[0]);
-    close(timerPipe_[0]);
-    close(timerPipe_[1]);
 }
 
 void senf::scheduler::detail::TimerDispatcher::add(TimerEvent & event)
 {
     TimerSet::iterator i (timers_.insert(event));
     senf::scheduler::detail::FIFORunner::instance().enqueue(&(*i));
-    if (! blocked_)
-        reschedule();
 }
 
 prefix_ void senf::scheduler::detail::TimerDispatcher::remove(TimerEvent & event)
@@ -90,32 +58,10 @@ prefix_ void senf::scheduler::detail::TimerDispatcher::remove(TimerEvent & event
         return;
     senf::scheduler::detail::FIFORunner::instance().dequeue(&(*i));
     timers_.erase(i);
-    if (! blocked_)
-        reschedule();
-}
-
-prefix_ void senf::scheduler::detail::TimerDispatcher::blockSignals()
-{
-    if (blocked_) 
-        return;
-    sigprocmask(SIG_BLOCK, &sigSet_, 0);
-    blocked_ = true;
-}
-
-prefix_ void senf::scheduler::detail::TimerDispatcher::unblockSignals()
-{
-    if (! blocked_)
-        return;
-    reschedule();
-    sigprocmask(SIG_UNBLOCK, &sigSet_, 0);
-    blocked_ = false;
 }
 
-prefix_ void senf::scheduler::detail::TimerDispatcher::signal(int events)
+prefix_ void senf::scheduler::detail::TimerDispatcher::prepareRun()
 {
-    siginfo_t info;
-    if (read(timerPipe_[0], &info, sizeof(info)) < int(sizeof(info)))
-        return;
     TimerSet::iterator i (timers_.begin());
     TimerSet::iterator const i_end (timers_.end());
     ClockService::clock_type now (senf::scheduler::detail::FdManager::instance().eventTime());
@@ -123,42 +69,12 @@ prefix_ void senf::scheduler::detail::TimerDispatcher::signal(int events)
         i->setRunnable();
 }
 
-prefix_ void senf::scheduler::detail::TimerDispatcher::sigHandler(int signal, 
-                                                                  ::siginfo_t * siginfo,
-                                                                  void *)
-{
-    // The manpage says, si_signo is unused in linux so we set it here
-    siginfo->si_signo = signal; 
-    // We can't do much on error anyway so we ignore errors here
-    if (siginfo->si_value.sival_ptr == 0)
-        return;
-    write(static_cast<TimerDispatcher*>(siginfo->si_value.sival_ptr)->timerPipe_[1], 
-          siginfo, sizeof(*siginfo));
-}
-
 prefix_ void senf::scheduler::detail::TimerDispatcher::reschedule()
 {
-    struct itimerspec timer;
-    memset(&timer, 0, sizeof(timer));
-    timer.it_interval.tv_sec = 0;
-    timer.it_interval.tv_nsec = 0;
-    if (timers_.empty()) {
-        SENF_LOG( (senf::log::VERBOSE)("Timer disabled") );
-        timer.it_value.tv_sec = 0;
-        timer.it_value.tv_nsec = 0;
-    }
-    else {
-        ClockService::clock_type next (timers_.begin()->timeout_);
-        if (next <= 0)
-            next = 1;
-        timer.it_value.tv_sec = ClockService::in_seconds(next);
-        timer.it_value.tv_nsec = ClockService::in_nanoseconds(
-            next - ClockService::seconds(timer.it_value.tv_sec));
-        SENF_LOG( (senf::log::VERBOSE)("Next timeout scheduled @" << timer.it_value.tv_sec << "." 
-                   << std::setw(9) << std::setfill('0') << timer.it_value.tv_nsec) );
-    }
-    if (timer_settime(timerId_, TIMER_ABSTIME, &timer, 0)<0)
-        SENF_THROW_SYSTEM_EXCEPTION("timer_settime()");
+    if (timers_.empty())
+        source_->notimeout();
+    else
+        source_->timeout(timers_.begin()->timeout_);
 }
 
 ///////////////////////////////////////////////////////////////////////////
index 8527380..5fcf5ef 100644 (file)
@@ -82,6 +82,16 @@ prefix_ void senf::scheduler::TimerEvent::timeout(ClockService::clock_type timeo
 ///////////////////////////////////////////////////////////////////////////
 // senf::scheduler::detail::TimerDispatcher
 
+prefix_ void senf::scheduler::detail::TimerDispatcher::enable()
+{
+    source_->enable();
+}
+
+prefix_ void senf::scheduler::detail::TimerDispatcher::disable()
+{
+    source_->disable();
+}
+
 prefix_ bool senf::scheduler::detail::TimerDispatcher::empty()
     const
 {
index 1c5ea52..af9c104 100644 (file)
@@ -27,7 +27,9 @@
 #define IH_SENF_Scheduler_TimerEvent_ 1
 
 // Custom includes
+#include <boost/scoped_ptr.hpp>
 #include "../boost/intrusive/iset.hpp"
+#include "TimerSource.hh"
 
 ///////////////////////////////ih.p////////////////////////////////////////
 
@@ -44,8 +46,7 @@ namespace detail {
     };
 
     class TimerDispatcher
-        : public detail::FdManager::Event,
-          public singleton<TimerDispatcher>
+        : public singleton<TimerDispatcher>
     {
         SENF_LOG_CLASS_AREA();
         
@@ -56,9 +57,12 @@ namespace detail {
         void add(TimerEvent & event);
         void remove(TimerEvent & event);
 
-        void unblockSignals();
-        void blockSignals();
-        
+        void enable();
+        void disable();
+
+        void prepareRun();
+        void reschedule();
+
         bool empty() const;
 
     protected:
@@ -67,20 +71,13 @@ namespace detail {
         TimerDispatcher();
         ~TimerDispatcher();
 
-        virtual void signal(int events);
-        static void sigHandler(int signal, ::siginfo_t * siginfo, void *);
-        void reschedule();
-
         typedef boost::intrusive::imultiset< TimerSetBase::value_traits<TimerEvent>,
                                              TimerSetCompare,
                                              false > TimerSet;
 
         TimerSet timers_;
 
-        int timerPipe_[2];
-        sigset_t sigSet_;
-        bool blocked_;
-        timer_t timerId_;
+        boost::scoped_ptr<TimerSource> source_;
 
         friend void senf::scheduler::restart();
         friend class singleton<TimerDispatcher>;
index b626944..cbab9f6 100644 (file)
@@ -61,10 +61,12 @@ BOOST_AUTO_UNIT_TEST(timerDispatcher)
         SENF_CHECK_NO_THROW( timer.disable() );
         SENF_CHECK_NO_THROW( timer.enable() );
         BOOST_CHECK( timer.enabled() );
-        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().unblockSignals() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().enable() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().reschedule() );
         SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() );
-        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().blockSignals() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().prepareRun() );
         SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().disable() );
         senf::ClockService::clock_type t2 (senf::ClockService::now());
         BOOST_CHECK( called );
         BOOST_CHECK( ! timer.enabled() );
@@ -74,10 +76,12 @@ BOOST_AUTO_UNIT_TEST(timerDispatcher)
         t = senf::ClockService::now();
         SENF_CHECK_NO_THROW( timer.timeout(t) );
         BOOST_CHECK( timer.enabled() );
-        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().unblockSignals() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().enable() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().reschedule() );
         SENF_CHECK_NO_THROW( senf::scheduler::detail::FdManager::instance().processOnce() );
-        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().blockSignals() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().prepareRun() );
         SENF_CHECK_NO_THROW( senf::scheduler::detail::FIFORunner::instance().run() );
+        SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().disable() );
         BOOST_CHECK_PREDICATE( is_close, (t) (senf::ClockService::now()) );
         BOOST_CHECK( called );
     }
diff --git a/Scheduler/TimerSource.cc b/Scheduler/TimerSource.cc
new file mode 100644 (file)
index 0000000..17d2de7
--- /dev/null
@@ -0,0 +1,162 @@
+// $Id$
+//
+// Copyright (C) 2009 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief TimerSource non-inline non-template implementation */
+
+#include "TimerSource.hh"
+//#include "TimerSource.ih"
+
+// Custom includes
+
+//#include "TimerSource.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::scheduler::detail::TimerSource
+
+prefix_ senf::scheduler::detail::TimerSource::~TimerSource()
+{}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::scheduler::detail::POSIXTimerSource
+
+prefix_ senf::scheduler::detail::POSIXTimerSource::POSIXTimerSource()
+    : timeoutEnabled_ (false), timeout_ (0), signalEnabled_ (false)
+{
+    if (pipe(timerPipe_) < 0)
+        SENF_THROW_SYSTEM_EXCEPTION("pipe()");
+    senf::scheduler::detail::FdManager::instance().set(
+        timerPipe_[0], detail::FdManager::EV_READ, this);
+    
+    sigemptyset(&sigSet_);
+    sigaddset(&sigSet_, SIGALRM);
+    sigprocmask(SIG_BLOCK, &sigSet_, 0);
+
+    struct sigaction act;
+    act.sa_sigaction = &sigHandler;
+    act.sa_mask = sigSet_;
+    act.sa_flags = SA_SIGINFO | SA_RESTART;
+    if (sigaction(SIGALRM, &act, 0) < 0)
+        SENF_THROW_SYSTEM_EXCEPTION("sigaction()");
+
+    struct sigevent ev;
+    ::memset(&ev, 0, sizeof(ev));
+    ev.sigev_notify = SIGEV_SIGNAL;
+    ev.sigev_signo = SIGALRM;
+    ev.sigev_value.sival_ptr = this;
+    if (timer_create(CLOCK_MONOTONIC, &ev, &timerId_) < 0)
+        SENF_THROW_SYSTEM_EXCEPTION("timer_create()");
+}
+
+prefix_ senf::scheduler::detail::POSIXTimerSource::~POSIXTimerSource()
+{
+    timer_delete(timerId_);
+    ::signal(SIGALRM, SIG_IGN);
+    sigprocmask(SIG_UNBLOCK, &sigSet_, 0);
+    senf::scheduler::detail::FdManager::instance().remove(timerPipe_[0]);
+    close(timerPipe_[0]);
+    close(timerPipe_[1]);
+}
+
+prefix_ void
+senf::scheduler::detail::POSIXTimerSource::timeout(ClockService::clock_type timeout)
+{
+    if (! timeoutEnabled_ || timeout_ != timeout) {
+        timeout_ = timeout;
+        if (timeout_ <= 0)
+            timeout_ = 1;
+        timeoutEnabled_ = true;
+        reschedule();
+    }
+}
+
+prefix_ void senf::scheduler::detail::POSIXTimerSource::notimeout()
+{
+    if (timeoutEnabled_) {
+        timeoutEnabled_ = false;
+        reschedule();
+    }
+}
+
+prefix_ void senf::scheduler::detail::POSIXTimerSource::enable()
+{
+    if (! signalEnabled_) {
+        signalEnabled_ = true;
+        sigprocmask(SIG_UNBLOCK, &sigSet_, 0);
+    }
+}
+
+prefix_ void senf::scheduler::detail::POSIXTimerSource::disable()
+{
+    if (signalEnabled_) {
+        signalEnabled_ = false;
+        sigprocmask(SIG_BLOCK, &sigSet_, 0);
+    }
+}
+
+prefix_ void senf::scheduler::detail::POSIXTimerSource::sigHandler(int,
+                                                                   ::siginfo_t * siginfo,
+                                                                   void *)
+{
+    if (siginfo->si_value.sival_ptr == 0)
+        return;
+    static char data = '\xD0';
+    write(static_cast<POSIXTimerSource*>(siginfo->si_value.sival_ptr)->timerPipe_[1], 
+          &data, sizeof(data));
+}
+
+prefix_ void senf::scheduler::detail::POSIXTimerSource::signal(int events)
+{
+    char data;
+    read(timerPipe_[0], &data, sizeof(data));
+    timeoutEnabled_ = false;
+}
+
+prefix_ void senf::scheduler::detail::POSIXTimerSource::reschedule()
+{
+    struct itimerspec timer;
+    memset(&timer, 0, sizeof(timer));
+    if (timeoutEnabled_) {
+        timer.it_value.tv_sec = ClockService::in_seconds(timeout_);
+        timer.it_value.tv_nsec = ClockService::in_nanoseconds(
+            timeout_ - ClockService::seconds(timer.it_value.tv_sec));
+    }
+    if (timer_settime(timerId_, TIMER_ABSTIME, &timer, 0)<0)
+        SENF_THROW_SYSTEM_EXCEPTION("timer_settime()");
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "TimerSource.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Scheduler/TimerSource.cci b/Scheduler/TimerSource.cci
new file mode 100644 (file)
index 0000000..de09775
--- /dev/null
@@ -0,0 +1,51 @@
+// $Id$
+//
+// Copyright (C) 2009 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief TimerSource inline non-template implementation */
+
+//#include "TimerSource.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::scheduler::detail::TimerSource
+
+prefix_ senf::scheduler::detail::TimerSource::TimerSource()
+{}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
diff --git a/Scheduler/TimerSource.hh b/Scheduler/TimerSource.hh
new file mode 100644 (file)
index 0000000..f17c6fc
--- /dev/null
@@ -0,0 +1,117 @@
+// $Id$
+//
+// Copyright (C) 2009 
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief TimerSource public header */
+
+#ifndef HH_SENF_Scheduler_TimerSource_
+#define HH_SENF_Scheduler_TimerSource_ 1
+
+// Custom includes
+#include <boost/utility.hpp>
+#include <signal.h>
+#include "ClockService.hh"
+#include "FdManager.hh"
+
+//#include "TimerSource.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace scheduler {
+namespace detail {
+
+    class TimerSource 
+        : boost::noncopyable
+    {
+    public:
+        virtual ~TimerSource();
+
+        virtual void timeout(ClockService::clock_type timeout) = 0;
+        virtual void notimeout() = 0;
+
+        virtual void enable() = 0;
+        virtual void disable() = 0;
+
+    protected:
+        TimerSource();
+    };
+
+    class POSIXTimerSource
+        : public detail::FdManager::Event, public TimerSource
+    {
+    public:
+        POSIXTimerSource();
+        ~POSIXTimerSource();
+
+        virtual void timeout(ClockService::clock_type timeout);
+        virtual void notimeout();
+
+        virtual void enable();
+        virtual void disable();
+
+    private:
+        static void sigHandler(int signal, ::siginfo_t * siginfo, void *);
+        virtual void signal(int events);
+        void reschedule();
+
+        bool timeoutEnabled_;
+        ClockService::clock_type timeout_;
+        int timerPipe_[2];
+        sigset_t sigSet_;
+        bool signalEnabled_;
+        timer_t timerId_;
+    };
+
+    class PollTimerSource
+        : public TimerSource
+    {
+    public:
+        virtual void timeout(ClockService::clock_type timeout);
+        virtual void disableTimeout();
+    };
+
+    class TimerFDTimerSource
+        : public TimerSource
+    {
+    public:
+        virtual void timeout(ClockService::clock_type timeout);
+        virtual void disableTimeout();
+    };
+
+}}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "TimerSource.cci"
+//#include "TimerSource.ct"
+//#include "TimerSource.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End: