TimerEventProxy.ct
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 
14 /** \file
15  \brief TimerEventProxy non-inline template implementation */
16 
17 // Custom includes
18 #include <senf/Utils/membind.hh>
19 #include <senf/Scheduler/Scheduler.hh>
20 
21 #define prefix_
22 //-/////////////////////////////////////////////////////////////////////////////////////////////////
23 
24 template<typename IdType>
25 prefix_ senf::scheduler::TimerEventProxy<IdType>::ChangeTimeout::ChangeTimeout(senf::ClockService::clock_type const & t)
26  : timeout_(t)
27 {}
28 
29 template<typename IdType>
30 prefix_ void senf::scheduler::TimerEventProxy<IdType>::ChangeTimeout::operator()(Entry & entry)
31 {
32  entry.timeout = timeout_;
33 }
34 
35 template<typename IdType>
36 prefix_ senf::scheduler::TimerEventProxy<IdType>::TimerEventProxy(std::string const & description, ClockService::clock_type const & callbackDurationThreshold, DurationExceededCallback decb)
37  : entrySetById_( entrySet_.template get<Id>()),
38  entrySetByTimeout_( entrySet_.template get<Timeout>()),
39  timer_( "TimerEventProxy " + description, membind(&TimerEventProxy<IdType>::timerEvent, this)),
40  callbackDurationThreshold_(callbackDurationThreshold),
41  durationExceededCallback_(decb)
42 {}
43 
44 template<typename IdType>
45 prefix_ void senf::scheduler::TimerEventProxy<IdType>::timerEvent()
46 {
47  ClockService::clock_type now (callbackDurationThreshold_ ? ClockService::now() : scheduler::now());
48  typename EntrySetByTimeout_t::iterator it = entrySetByTimeout_.begin();
49  while (it != entrySetByTimeout_.end() && it->timeout <= now) {
50  Entry item (*it);
51  // remove due entry from set
52  entrySetByTimeout_.erase(it);
53  // call callback
54  item.cb(now, item.id);
55  it = entrySetByTimeout_.begin();
56  if (callbackDurationThreshold_) {
57  ClockService::clock_type tend ( ClockService::now());
58  callbackDurations_.accumulate(ClockService::in_milliseconds(tend - now));
59  if (durationExceededCallback_ and ((tend - now) > callbackDurationThreshold_)) {
60  durationExceededCallback_(item.id, tend - now, callbackDurations_.data());
61  }
62  now = tend;
63  }
64  }
65  if (entrySet_.size() > 0)
66  timer_.timeout(entrySetByTimeout_.begin()->timeout);
67 }
68 
69 template<typename IdType>
70 prefix_ void senf::scheduler::TimerEventProxy<IdType>::add(
71  ClockService::clock_type const &timeout, IdType const & id, Callback cb)
72 {
73  // insert new entry or replace the timeout of an entry already indexed
74  typename EntrySetById_t::iterator it = entrySetById_.find(id);
75  if (it == entrySetById_.end())
76  entrySet_.insert( Entry(timeout, id, cb));
77  else
78  entrySetById_.modify( it, ChangeTimeout(timeout));
79  // the scheduler time to the first earliest timeout (ordered index)
80  timer_.timeout( entrySetByTimeout_.begin()->timeout);
81 }
82 
83 template<typename IdType>
84 prefix_ bool senf::scheduler::TimerEventProxy<IdType>::remove(IdType const & id)
85 {
86  bool removed (entrySetById_.erase(id) > 0);
87  if (entrySet_.size() > 0)
88  timer_.timeout(entrySetByTimeout_.begin()->timeout);
89  else
90  timer_.disable();
91  return removed;
92 }
93 
94 template<typename IdType>
95 prefix_ senf::ClockService::clock_type senf::scheduler::TimerEventProxy<IdType>::timeout(IdType const & id)
96  const
97 {
98  typename EntrySetById_t::const_iterator it (entrySetById_.find( id));
99  return it == entrySetById_.end() ? ClockService::clock_type(0) : it->timeout;
100 }
101 
102 template<typename IdType>
103 prefix_ std::vector<std::pair<senf::ClockService::clock_type, IdType> > senf::scheduler::TimerEventProxy<IdType>::list()
104  const
105 {
106  std::vector<std::pair<ClockService::clock_type, IdType> > tmp;
107  typename EntrySetByTimeout_t::const_iterator it;
108  for (it = entrySetByTimeout_.begin(); it != entrySetByTimeout_.end(); ++it)
109  tmp.push_back(std::make_pair( it->timeout, it->id));
110  return tmp;
111 }
112 
113 template<typename IdType>
114 prefix_ unsigned senf::scheduler::TimerEventProxy<IdType>::numEvents()
115  const
116 {
117  return entrySet_.size();
118 }
119 
120 template<typename IdType>
121 prefix_ void senf::scheduler::TimerEventProxy<IdType>::clear()
122 {
123  entrySet_.clear();
124  timer_.disable();
125 }
126 
127 template<typename IdType>
128 prefix_ senf::StatisticsData senf::scheduler::TimerEventProxy<IdType>::callbackDurationStats()
129 {
130  auto tmp (callbackDurations_.data());
131  callbackDurations_.clear();
132  return tmp;
133 }
134 
135 
136 //-/////////////////////////////////////////////////////////////////////////////////////////////////
137 #undef prefix_
138 
139 
140 // Local Variables:
141 // mode: c++
142 // fill-column: 100
143 // c-file-style: "senf"
144 // indent-tabs-mode: nil
145 // ispell-local-dictionary: "american"
146 // compile-command: "scons -u test"
147 // comment-column: 40
148 // End:
149 
150