Scheduler.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
25 #include "Scheduler.hh"
26 //#include "Scheduler.ih"
27 
28 // Custom includes
29 
30 #define prefix_
31 //-/////////////////////////////////////////////////////////////////////////////////////////////////
32 
33 namespace {
34  bool terminate_ (false);
35  bool running_ (false);
36 }
37 
39 {
40  terminate_ = true;
41 }
42 
44 {
45  return running_;
46 }
47 
49 {
50  detail::FIFORunner::instance().yield();
51 }
52 
53 namespace {
54 
55  // We don't want try { } catch(...) { ... throw; } since that will make debugging more
56  // difficult: the stack backtrace for an unexpected exception would always end here.
57  struct SchedulerScopedInit
58  {
59  SchedulerScopedInit()
60  {
62  senf::scheduler::detail::SignalDispatcher::instance().unblockSignals();
63  senf::scheduler::detail::TimerDispatcher::instance().enable();
64  running_ = true;
65  }
66 
67  ~SchedulerScopedInit()
68  {
69  senf::scheduler::detail::TimerDispatcher::instance().disable();
70  senf::scheduler::detail::SignalDispatcher::instance().blockSignals();
72  running_ = false;
73  }
74  };
75 }
76 
78 {
79  SchedulerScopedInit initScheduler;
80  terminate_ = false;
81  detail::TimerDispatcher::instance().reschedule();
82  while(! terminate_ && ! (detail::FdDispatcher::instance().empty() &&
83  detail::TimerDispatcher::instance().empty() &&
84  detail::FileDispatcher::instance().empty() &&
85  detail::IdleEventDispatcher::instance().empty()) ) {
86  detail::FdManager::instance().processOnce();
87  detail::FileDispatcher::instance().prepareRun();
88  detail::EventHookDispatcher::instance().prepareRun();
89  detail::TimerDispatcher::instance().prepareRun();
90  detail::IdleEventDispatcher::instance().prepareRun();
91  detail::FIFORunner::instance().run();
92  detail::TimerDispatcher::instance().reschedule();
93  }
94 }
95 
97 {
98  detail::FdManager* fdm (&detail::FdManager::instance());
99  detail::FIFORunner* ffr (&detail::FIFORunner::instance());
100  detail::FdDispatcher* fdd (&detail::FdDispatcher::instance());
101  detail::TimerDispatcher* tdd (&detail::TimerDispatcher::instance());
102  detail::SignalDispatcher* sdd (&detail::SignalDispatcher::instance());
103  detail::FileDispatcher* fld (&detail::FileDispatcher::instance());
104  detail::IdleEventDispatcher* ied (&detail::IdleEventDispatcher::instance());
105  detail::EventHookDispatcher* eed (&detail::EventHookDispatcher::instance());
106 
107  eed->~EventHookDispatcher();
108  ied->~IdleEventDispatcher();
109  fld->~FileDispatcher();
110  sdd->~SignalDispatcher();
111  tdd->~TimerDispatcher();
112  fdd->~FdDispatcher();
113  ffr->~FIFORunner();
114  fdm->~FdManager();
115 
116  new (fdm) detail::FdManager();
117  new (ffr) detail::FIFORunner();
118  new (fdd) detail::FdDispatcher();
119  new (tdd) detail::TimerDispatcher();
120  new (sdd) detail::SignalDispatcher();
121  new (fld) detail::FileDispatcher();
122  new (ied) detail::IdleEventDispatcher();
123  new (eed) detail::EventHookDispatcher();
124 }
125 
127 {
128  return detail::FdDispatcher::instance().empty()
129  && detail::TimerDispatcher::instance().empty()
130  && detail::FileDispatcher::instance().empty()
131  && detail::SignalDispatcher::instance().empty()
132  && detail::IdleEventDispatcher::instance().empty()
133  && detail::EventHookDispatcher::instance().empty();
134 }
135 
137 {
138 #ifdef HAVE_TIMERFD_CREATE
140  detail::TimerDispatcher::instance().timerSource(
141  std::unique_ptr<detail::TimerSource>(new detail::TimerFDTimerSource()));
142  else
143 #endif
144  detail::TimerDispatcher::instance().timerSource(
145  std::unique_ptr<detail::TimerSource>(new detail::POSIXTimerSource()));
146 }
147 
148 //-/////////////////////////////////////////////////////////////////////////////////////////////////
149 // senf::schedulerLogTimeSource
150 
152  const
153 {
155 }
156 
157 //-/////////////////////////////////////////////////////////////////////////////////////////////////
158 // senf::scheduler::BlockSignals
159 
161  : blocked_ (false)
162 {
163  ::sigfillset(&allSigs_);
164  if (initiallyBlocked)
165  block();
166 }
167 
169 {
170  if (blocked_)
171  return;
172  ::sigprocmask(SIG_BLOCK, &allSigs_, &savedSigs_);
173  blocked_ = true;
174 }
175 
177 {
178  if (!blocked_)
179  return;
180  ::sigprocmask(SIG_SETMASK, &savedSigs_, 0);
181  blocked_ = false;
182 }
183 
184 //-/////////////////////////////////////////////////////////////////////////////////////////////////
185 #undef prefix_
186 
187 
188 // Local Variables:
189 // mode: c++
190 // fill-column: 100
191 // c-file-style: "senf"
192 // indent-tabs-mode: nil
193 // ispell-local-dictionary: "american"
194 // compile-command: "scons -u test"
195 // comment-column: 40
196 // End:
bool empty()
Return true, if no event is registered, false otherwise.
Definition: Scheduler.cc:126
#define prefix_
Definition: Scheduler.cc:30
void hiresTimers()
Switch to using hi resolution timers.
Definition: Scheduler.cc:136
Scheduler public header.
ClockService::clock_type const & now()
Return (approximate) current time.
void process()
Event handler main loop.
Definition: Scheduler.cc:77
void terminate()
Called by callbacks to terminate the main loop.
Definition: Scheduler.cc:38
BlockSignals(bool initiallyBlocked=true)
Block signals until end of scope.
Definition: Scheduler.cc:160
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_nanoseconds(clock_type const &v)
Convert v to nanoseconds.
bool haveScalableHiresTimers()
return true, if timerfd() timing is available, false otherwise
senf::log::time_type operator()() const
Definition: Scheduler.cc:151
bool running()
true, if scheduler is running, false otherwise
Definition: Scheduler.cc:43
void restart()
Restart scheduler.
Definition: Scheduler.cc:96
void yield()
Immediately rescheduler.
Definition: Scheduler.cc:48
void block()
Block signals if not blocked.
Definition: Scheduler.cc:168
void unblock()
Unblock signals if blocked.
Definition: Scheduler.cc:176