Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Scheduler.cc

Go to the documentation of this file.
00001 // $Id: Scheduler.cc 1772 2011-03-10 12:45:21Z tho $
00002 //
00003 // Copyright (C) 2006
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00034 #include "Scheduler.hh"
00035 //#include "Scheduler.ih"
00036 
00037 // Custom includes
00038 
00039 #define prefix_
00040 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00041 
00042 namespace {
00043     bool terminate_ (false);
00044     bool running_ (false);
00045 }
00046 
00047 prefix_ void senf::scheduler::terminate()
00048 {
00049     terminate_ = true;
00050 }
00051 
00052 prefix_ void senf::scheduler::yield()
00053 {
00054     detail::FIFORunner::instance().yield();
00055 }
00056 
00057 prefix_ bool senf::scheduler::running()
00058 {
00059     return running_;
00060 }
00061 
00062 prefix_ senf::ClockService::clock_type senf::scheduler::now()
00063 {
00064     return running() ? eventTime() : ClockService::now();
00065 }
00066 
00067 namespace {
00068 
00069     // We don't want try { } catch(...) { ... throw; } since that will make debugging more
00070     // difficult: the stack backtrace for an unexpected exception would always end here.
00071     struct SchedulerScopedInit
00072     {
00073         SchedulerScopedInit()
00074             {
00075                 senf::scheduler::detail::FIFORunner::instance().startWatchdog();
00076                 senf::scheduler::detail::SignalDispatcher::instance().unblockSignals();
00077                 senf::scheduler::detail::TimerDispatcher::instance().enable();
00078                 running_ = true;
00079             }
00080 
00081         ~SchedulerScopedInit()
00082             {
00083                 senf::scheduler::detail::TimerDispatcher::instance().disable();
00084                 senf::scheduler::detail::SignalDispatcher::instance().blockSignals();
00085                 senf::scheduler::detail::FIFORunner::instance().stopWatchdog();
00086                 running_ = false;
00087             }
00088     };
00089 }
00090 
00091 prefix_ void senf::scheduler::process()
00092 {
00093     SchedulerScopedInit initScheduler;
00094     terminate_ = false;
00095     detail::TimerDispatcher::instance().reschedule();
00096     while(! terminate_ && ! (detail::FdDispatcher::instance().empty() &&
00097                              detail::TimerDispatcher::instance().empty() &&
00098                              detail::FileDispatcher::instance().empty() &&
00099                              detail::IdleEventDispatcher::instance().empty()) ) {
00100         detail::FdManager::instance().processOnce();
00101         detail::FileDispatcher::instance().prepareRun();
00102         detail::EventHookDispatcher::instance().prepareRun();
00103         detail::TimerDispatcher::instance().prepareRun();
00104         detail::IdleEventDispatcher::instance().prepareRun();
00105         detail::FIFORunner::instance().run();
00106         detail::TimerDispatcher::instance().reschedule();
00107     }
00108 }
00109 
00110 prefix_ void senf::scheduler::restart()
00111 {
00112     detail::FdManager*            fdm (&detail::FdManager::instance());
00113     detail::FIFORunner*           ffr (&detail::FIFORunner::instance());
00114     detail::FdDispatcher*         fdd (&detail::FdDispatcher::instance());
00115     detail::TimerDispatcher*      tdd (&detail::TimerDispatcher::instance());
00116     detail::SignalDispatcher*     sdd (&detail::SignalDispatcher::instance());
00117     detail::FileDispatcher*       fld (&detail::FileDispatcher::instance());
00118     detail::IdleEventDispatcher*  ied (&detail::IdleEventDispatcher::instance());
00119     detail::EventHookDispatcher*  eed (&detail::EventHookDispatcher::instance());
00120 
00121     eed->~EventHookDispatcher();
00122     ied->~IdleEventDispatcher();
00123     fld->~FileDispatcher();
00124     sdd->~SignalDispatcher();
00125     tdd->~TimerDispatcher();
00126     fdd->~FdDispatcher();
00127     ffr->~FIFORunner();
00128     fdm->~FdManager();
00129 
00130     new (fdm) detail::FdManager();
00131     new (ffr) detail::FIFORunner();
00132     new (fdd) detail::FdDispatcher();
00133     new (tdd) detail::TimerDispatcher();
00134     new (sdd) detail::SignalDispatcher();
00135     new (fld) detail::FileDispatcher();
00136     new (ied) detail::IdleEventDispatcher();
00137     new (eed) detail::EventHookDispatcher();
00138 }
00139 
00140 prefix_ bool senf::scheduler::empty()
00141 {
00142     return detail::FdDispatcher::instance().empty()
00143         && detail::TimerDispatcher::instance().empty()
00144         && detail::FileDispatcher::instance().empty()
00145         && detail::SignalDispatcher::instance().empty()
00146         && detail::IdleEventDispatcher::instance().empty()
00147         && detail::EventHookDispatcher::instance().empty();
00148 }
00149 
00150 prefix_ void senf::scheduler::hiresTimers()
00151 {
00152 #ifdef HAVE_TIMERFD_CREATE
00153     if (haveScalableHiresTimers())
00154         detail::TimerDispatcher::instance().timerSource(
00155             std::auto_ptr<detail::TimerSource>(new detail::TimerFDTimerSource()));
00156     else
00157 #endif
00158         detail::TimerDispatcher::instance().timerSource(
00159             std::auto_ptr<detail::TimerSource>(new detail::POSIXTimerSource()));
00160 }
00161 
00162 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00163 // senf::schedulerLogTimeSource
00164 
00165 prefix_ senf::log::time_type senf::scheduler::LogTimeSource::operator()()
00166     const
00167 {
00168     return scheduler::now();
00169 }
00170 
00171 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00172 // senf::scheduler::BlockSignals
00173 
00174 prefix_ senf::scheduler::BlockSignals::BlockSignals(bool initiallyBlocked)
00175     : blocked_ (false)
00176 {
00177     ::sigfillset(&allSigs_);
00178     if (initiallyBlocked)
00179         block();
00180 }
00181 
00182 prefix_ void senf::scheduler::BlockSignals::block()
00183 {
00184     if (blocked_)
00185         return;
00186     ::sigprocmask(SIG_BLOCK, &allSigs_, &savedSigs_);
00187     blocked_ = true;
00188 }
00189 
00190 prefix_ void senf::scheduler::BlockSignals::unblock()
00191 {
00192     if (!blocked_)
00193         return;
00194     ::sigprocmask(SIG_SETMASK, &savedSigs_, 0);
00195     blocked_ = false;
00196 }
00197 
00198 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00199 #undef prefix_
00200 
00201 
00202 // Local Variables:
00203 // mode: c++
00204 // fill-column: 100
00205 // c-file-style: "senf"
00206 // indent-tabs-mode: nil
00207 // ispell-local-dictionary: "american"
00208 // compile-command: "scons -u test"
00209 // comment-column: 40
00210 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research