new timer event proxy to reduce scheduler load
[senf.git] / senf / Scheduler / TimerEventProxy.hh
1 // $Id$
2 //
3 // Copyright (C) 2010
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Mathias Kretschmer <mtk@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24  \brief TimerEventProxy public header */
25
26 #ifndef HH_SENF_Scheduler_TimerEventProxy_
27 #define HH_SENF_Scheduler_TimerEventProxy_ 1
28
29 #ifdef SENF_DEBUG
30 #   define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
31 #   define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
32 #endif
33
34 #include <boost/range/iterator_range.hpp>
35 #include <boost/multi_index_container.hpp>
36 #include <boost/multi_index/ordered_index.hpp>
37 #include <boost/multi_index/hashed_index.hpp>
38 #include <boost/multi_index/sequenced_index.hpp>
39 #include <boost/multi_index/key_extractors.hpp>
40 #include <boost/multi_index/random_access_index.hpp>
41 #include <boost/multi_index/identity.hpp>
42 #include <boost/multi_index/member.hpp>
43
44 #include <senf/Scheduler/ClockService.hh>
45 #include <senf/Scheduler/TimerEvent.hh>
46 #include <senf/Utils/Console/Console.hh>
47
48 namespace senf {
49 namespace scheduler {
50
51
52     /** \brief Deadline timer proxy
53
54         The TimerEventProxy is meant to host long term deadline timers to reduce the load of the
55         Scheduler with a hugh count of TimerEvent items. It registers deadline timer callbacks which
56         will be called when the timer expires.
57
58         The functionality is based on one TimerEvent instance per TimerEventProxy instance and could
59         host a big count of timers.
60      */
61     template<class T>
62     class TimerEventProxy {
63     private:
64
65         template<class T_>
66         struct Entry {
67         public:
68             senf::ClockService::clock_type timeout;
69             T id;
70             boost::function<void(senf::ClockService::clock_type, T_ const &)> fkt;
71
72             bool operator<(const Entry<T_> & e) const {
73                 return id < e.id;
74             }
75             //  bool operator==(const Entry<T> &e)const{return id == e.id;}
76             Entry(senf::ClockService::clock_type _timeout, T_ _id, boost::function<void(
77                     senf::ClockService::clock_type, T_)> _fkt) :
78                 timeout(_timeout), id(_id), fkt(_fkt) {
79             }
80         };
81
82
83         senf::scheduler::TimerEvent timer;
84
85         //
86         // data structure to hold active timers
87         //
88         struct Timeout {};
89         struct Id {};
90         typedef boost::multi_index_container<Entry<T> ,
91                 boost::multi_index::indexed_by<
92                         boost::multi_index::ordered_non_unique<
93                                 boost::multi_index::tag<Timeout>,
94                                 boost::multi_index::member<Entry<T> ,
95                                         senf::ClockService::clock_type,
96                                         &Entry<T>::timeout> >,
97                         boost::multi_index::ordered_unique<boost::multi_index::tag<
98                                 Id>, boost::multi_index::identity<Entry<T> > > > >
99                 EntrySet;
100
101         typedef typename EntrySet::template index<Timeout>::type
102                 EntrySetByTimeout_t;
103         typedef typename EntrySet::template index<Id>::type EntrySetById_t;
104
105         EntrySet entrySet;
106         EntrySetById_t & entrySetById;
107         EntrySetByTimeout_t & entrySetByTimeout;
108
109     private:
110         // callback for the Scheduler timer event
111         void timerEvent();
112
113     public:
114         ///////////////////////////////////////////////////////////////////////////
115         // Types
116         typedef boost::function<void(senf::ClockService::clock_type, T const &)> Callback;
117
118         TimerEventProxy();
119         ///< Instantiate a TimerEventProxy
120
121         TimerEventProxy(std::string const & name, senf::console::DirectoryNode & node);
122         ///< Instantiate a TimerEventProxy and add the list command to the give DirectoryNode
123
124         void add(senf::ClockService::clock_type timeout, T const &id, Callback cb);
125         ///< Add new deadline timer
126         bool del(T const & id);
127         ///< Remove timer by given \a id.
128         std::vector<std::pair<senf::ClockService::clock_type, T> > list();
129         ///< Returns a vector of all active timers with timeout and id.
130     };
131 }
132 }
133
134 #include "TimerEventProxy.ct"
135
136 #endif