An Overlay-based
Virtual Network Substrate
SpoVNet

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

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

added new interface: SystemQueue::am_I_in_the_SysQ_thread

for debugging and asserts..

File size: 7.8 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     * NOTE: Do not call this function from within a SystemQueue-Event.
121     *   Use SystemQueue::leave() instead.
122         *
123         * This method is thread-safe.
124         */
125        void cancel();
126   
127    /**
128     * Like SystemQueue::cancel(), but may only be called from within a SystemQueue-Event.
129     *
130     * NOTE: In this case some cleanup can not be made. -- If the SystemQueue is
131     *   restarted, SystemQueue::cancel() must be called before SystemQueue::run()
132     *   can be called again.
133     */
134    void leave();
135   
136    /**
137     * Join the SystemQueue thread -- the current thread is blocked until the
138     * SystemQueue finishes.
139     *
140     * NOTE: Use this only in combination with SystemQueue::leave()
141     *
142     * [ There is a possible race condition with SystemQueue::cancel(), but
143     *   SystemQueue::join() should not be used at the same time as
144     *   SystemQueue::cancel() anyway. (SystemQueue::leave() is fine, though.)
145     */
146    void join();
147
148        /**
149         * Drop all queued events for that listener
150         */
151        void dropAll( const SystemEventListener* mlistener);
152
153        /**
154         * Check wheter this queue has items or not.
155         *
156         * @return True, if this queue is empty.
157         */
158        bool isEmpty();
159
160        /**
161         * Is the system queue already started and running?
162         *
163         * @return TRUE, if the system queue is running. | FALSE otherwise
164         */
165        bool isRunning();
166   
167    /**
168     *  NOTE: This function is for debugging and asserts only!!
169     *
170     *  @return TRUE if called from the SysQ thread (from inside a SystemEvent)
171     *          | FALSE if it's called from another thread
172     */
173    bool am_I_in_the_SysQ_thread();
174
175protected:
176
177        /**
178         * Aqcuire the mutex
179         */
180        void enterMethod();
181
182        /**
183         * Leave the mutex
184         */
185        void leaveMethod();
186
187        /**
188         * Constructs a system queue.
189         */
190        SystemQueue();
191
192        /**
193         * Destroys the system queue. Beware that all events
194         * are canceled
195         */
196        ~SystemQueue();
197       
198
199/**
200 *  inner class of class SystemQueue:
201 *
202 *  QueueThread  --  the class the does the actual work
203 */
204private:
205
206typedef list<SystemEvent> EventQueue;
207typedef std::priority_queue<SystemEvent, 
208                            std::vector<SystemEvent>,  // [ TODO is vector the best underlay? ]
209                            std::greater<SystemEvent> > PriorityEventQueue;
210
211        //********************************************************
212
213        class QueueThread
214        {
215        friend class SystemQueue;
216       
217        public:
218                QueueThread();
219                virtual ~QueueThread();
220       
221        /// main loop -- called from boost::thread
222        void operator()();
223       
224//              void run();
225                void cancel();
226                bool isEmpty();
227                void insert( SystemEvent& event, uint32_t delay );
228                void enter();
229                void leave();
230                void dropAll( const SystemEventListener* mlistener);
231        bool isRunning();
232
233    private:
234       
235        /// main loop functions
236        void run_immediate_event();
237        void check_timed_queue();
238        void wait_for_next_deadline();
239       
240        /// makes sure that always the same clock is used
241        ptime get_clock();
242       
243       
244        private:
245        EventQueue immediateEventsQ;
246        PriorityEventQueue timedEventsQ;
247       
248        boost::condition_variable system_queue_idle;
249        boost::mutex queue_mutex;
250
251        bool processing_event;
252       
253                volatile bool running;
254        volatile bool aborted;
255        volatile bool unclean;
256        }; // class QueueThread
257
258       
259/// inner class of class SystemQueue
260private:
261    /**
262     * This inner class handles the function-call events.
263     * @see SystemQueue::scheduleCall
264     */
265    class FunctionCaller  :  public SystemEventListener
266    {
267        void handleSystemEvent(const SystemEvent& event)
268        {
269            boost::function0<void>* function_ptr = event.getData< boost::function0<void> >();
270            (*function_ptr)();
271            delete function_ptr;
272        }
273    };
274
275    FunctionCaller internal_function_caller;
276   
277   
278   
279    /// member variables of class SystemQueue
280private:
281    boost::scoped_ptr<QueueThread> SysQ;
282    boost::scoped_ptr<boost::thread> sysq_thread;
283   
284//  volatile bool systemQueueRunning;
285
286}; // class SystemQueue
287
288}} // spovnet, common
289
290#endif /* SYSTEMQUEUE_H_ */
Note: See TracBrowser for help on using the repository browser.