source: source/ariba/utility/system/SystemQueue.h@ 12763

Last change on this file since 12763 was 12763, checked in by hock@…, 10 years ago

priority queue (but not tested)

--> FIXME in SystemEvent.h (has to be fixed first!)

File size: 6.7 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#ifndef SYSTEMQUEUE_H_
40#define SYSTEMQUEUE_H_
41
42#include "SystemEvent.h"
43#include "SystemEventListener.h"
44#include "ariba/utility/logging/Logging.h"
45
46#include <cassert>
47#include <list>
48#include <vector>
49#include <queue> // std::priority_queue
50#include <functional> // std::greater
51
52#include <boost/date_time.hpp>
53#include <boost/cstdint.hpp>
54#include <boost/scoped_ptr.hpp>
55
56#include <boost/thread/mutex.hpp>
57#include <boost/thread/thread.hpp>
58#include <boost/thread/condition_variable.hpp>
59#include <boost/utility.hpp>
60#include <boost/bind.hpp>
61
62#include <boost/function.hpp>
63
64namespace ariba {
65namespace utility {
66
67using std::list;
68using boost::posix_time::ptime;
69
70
71/**
72 * This class implements a simple system event queue to allow
73 * a simulation of cooperative multitasking. It also allows
74 * events to be scheduled from other tasks. This allows
75 * dispatching asynchronous tasks.
76 *
77 * @author Christoph Mayer, Sebastian Mies
78 */
79/** XXX Mario Hock -- reworking the entire module **/
80
81
82class SystemQueue : private boost::noncopyable
83{
84 use_logging_h(SystemQueue);
85 friend class EnterMethod;
86public:
87 /**
88 * Get the SystemQueue singleton instance.
89 */
90 static SystemQueue& instance();
91
92 /**
93 * This methods schedules a given event.
94 *
95 * @param The event to be scheduled
96 * @param The delay in milli-seconds
97 */
98 void scheduleEvent( const SystemEvent& event, uint32_t delay = 0 );
99
100 /**
101 * This method schedules a function call in the SystemQueue.
102 * (Like scheduleEvent, but to be used with boost::bind.)
103 *
104 * @param function: The function to be called [void function()]
105 * @param The delay in milli-seconds
106 */
107 void scheduleCall( const boost::function0<void>& function, uint32_t delay = 0 );
108
109 /**
110 * Starts the processing and waiting for events.
111 * Use <code>cancel()</code> to end system queue processing and
112 * <code>isEmpty()</code> to check wheter the queue is empty.
113 */
114 void run();
115
116 /**
117 * Cancels the system queue and ends the processing after the
118 * currently processed event is processed.
119 *
120 * This method is thread-safe.
121 */
122 void cancel();
123
124 /**
125 * Drop all queued events for that listener
126 */
127 void dropAll( const SystemEventListener* mlistener);
128
129 /**
130 * Check wheter this queue has items or not.
131 *
132 * @return True, if this queue is empty.
133 */
134 bool isEmpty();
135
136 /**
137 * Is the system queue already started and running?
138 *
139 * @return True, if the system queue is running.
140 */
141 bool isRunning();
142
143protected:
144
145 /**
146 * Aqcuire the mutex
147 */
148 void enterMethod();
149
150 /**
151 * Leave the mutex
152 */
153 void leaveMethod();
154
155 /**
156 * Constructs a system queue.
157 */
158 SystemQueue();
159
160 /**
161 * Destroys the system queue. Beware that all events
162 * are canceled
163 */
164 ~SystemQueue();
165
166
167/**
168 * inner class of class SystemQueue:
169 *
170 * QueueThread -- the class the does the actual work
171 */
172private:
173
174typedef list<SystemEvent> EventQueue;
175typedef std::priority_queue<SystemEvent,
176 std::vector<SystemEvent>,
177 std::greater<SystemEvent> > PriorityEventQueue;
178// typedef std::priority_queue<SystemEvent> PriorityEventQueue;
179// TODO is vector the best underlay?
180
181
182 //********************************************************
183
184 class QueueThread
185 {
186 friend class SystemQueue;
187
188 public:
189 QueueThread();
190 virtual ~QueueThread();
191
192 /// main loop -- called from boost::thread
193 void operator()();
194
195// void run();
196 void cancel();
197 bool isEmpty();
198 void insert( SystemEvent& event, uint32_t delay );
199 void enter();
200 void leave();
201 void dropAll( const SystemEventListener* mlistener);
202 bool isRunning();
203
204 private:
205
206 /// main loop functions
207 void run_immediate_event();
208 void check_timed_queue();
209 void wait_for_next_deadline();
210
211 /// makes sure that always the same clock is used
212 ptime get_clock();
213
214
215 private:
216 EventQueue immediateEventsQ;
217 PriorityEventQueue timedEventsQ;
218
219 boost::condition_variable system_queue_idle;
220 boost::mutex queue_mutex;
221
222 bool processing_event;
223
224 volatile bool running;
225 volatile bool aborted;
226 }; // class QueueThread
227
228
229/// inner class of class SystemQueue
230private:
231 /**
232 * This inner class handles the function-call events.
233 * @see SystemQueue::scheduleCall
234 */
235 class FunctionCaller : public SystemEventListener
236 {
237 void handleSystemEvent(const SystemEvent& event)
238 {
239 boost::function0<void>* function_ptr = event.getData< boost::function0<void> >();
240 (*function_ptr)();
241 delete function_ptr;
242 }
243 };
244
245 FunctionCaller internal_function_caller;
246
247
248
249 /// member variables of class SystemQueue
250private:
251 boost::scoped_ptr<QueueThread> SysQ;
252 boost::scoped_ptr<boost::thread> sysq_thread;
253
254// volatile bool systemQueueRunning;
255
256}; // class SystemQueue
257
258}} // spovnet, common
259
260#endif /* SYSTEMQUEUE_H_ */
Note: See TracBrowser for help on using the repository browser.