00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef SYSTEMQUEUE_H_
00040 #define SYSTEMQUEUE_H_
00041
00042 #include <vector>
00043 #include <cassert>
00044 #include "SystemEvent.h"
00045 #include "SystemEventListener.h"
00046 #include "ariba/utility/logging/Logging.h"
00047 #include <boost/date_time.hpp>
00048 #include <boost/cstdint.hpp>
00049
00050 #ifdef UNDERLAY_OMNET
00051 #include <csimplemodule.h>
00052 #include <cmessage.h>
00053 #include <macros.h>
00054 #else
00055 #include <boost/thread/mutex.hpp>
00056 #include <boost/thread/thread.hpp>
00057 #include <boost/thread/condition_variable.hpp>
00058 #include <boost/utility.hpp>
00059 #include <boost/bind.hpp>
00060 #endif
00061
00062 using std::vector;
00063 using boost::posix_time::ptime;
00064
00065 namespace ariba {
00066 namespace utility {
00067
00077 #ifndef UNDERLAY_OMNET
00078 class SystemQueue : private boost::noncopyable {
00079 #else
00080 class SystemQueue : public cSimpleModule {
00081 #endif
00082
00083 use_logging_h(SystemQueue);
00084 friend class EnterMethod;
00085 public:
00089 static SystemQueue& instance() {
00090 static SystemQueue _inst;
00091 return _inst;
00092 }
00093
00094 #ifdef UNDERLAY_OMNET
00095
00100 virtual void deleteModule(){}
00101 #endif
00102
00109 void scheduleEvent( const SystemEvent& event, uint32_t delay = 0 );
00110
00116 void run();
00117
00124 void cancel();
00125
00131 bool isEmpty();
00132
00138 bool isRunning();
00139
00140 protected:
00141
00145 void enterMethod();
00146
00150 void leaveMethod();
00151
00155 SystemQueue();
00156
00161 ~SystemQueue();
00162
00163 #ifdef UNDERLAY_OMNET
00164 virtual void handleMessage( cMessage* msg );
00165 #endif
00166
00167 private:
00168
00169 #ifndef UNDERLAY_OMNET
00170 typedef vector<SystemEvent> EventQueue;
00171
00172
00173
00174 class QueueThread {
00175 public:
00176 QueueThread(QueueThread* _transferQueue = NULL);
00177 virtual ~QueueThread();
00178 void run();
00179 void cancel();
00180 bool isEmpty();
00181 void insert( const SystemEvent& event, uint32_t delay );
00182 void enter();
00183 void leave();
00184
00185 protected:
00186 virtual void onItemInserted( const SystemEvent& event ) = 0;
00187 virtual void onNextQueueItem( const SystemEvent& event ) = 0;
00188 QueueThread* transferQueue;
00189 EventQueue eventsQueue;
00190 boost::mutex queueMutex;
00191 private:
00192 boost::thread* queueThread;
00193 static void threadFunc( QueueThread* obj );
00194 boost::condition_variable itemsAvailable;
00195 volatile bool running;
00196 };
00197
00198
00199
00200 class QueueThreadDirect : public QueueThread {
00201 public:
00202 QueueThreadDirect();
00203 ~QueueThreadDirect();
00204 protected:
00205 virtual void onItemInserted( const SystemEvent& event );
00206 virtual void onNextQueueItem( const SystemEvent& event );
00207 };
00208
00209
00210
00211 class QueueThreadDelay : public QueueThread {
00212 public:
00213 QueueThreadDelay(QueueThread* _transferQueue = NULL);
00214 ~QueueThreadDelay();
00215 protected:
00216 virtual void onItemInserted( const SystemEvent& event );
00217 virtual void onNextQueueItem( const SystemEvent& event );
00218 private:
00219 volatile bool isSleeping;
00220 ptime sleepStart;
00221 boost::mutex sleepMutex;
00222 boost::condition_variable sleepCond;
00223 };
00224
00225
00226
00227 QueueThreadDirect directScheduler;
00228 QueueThreadDelay delayScheduler;
00229 volatile bool systemQueueRunning;
00230 #endif
00231
00232 };
00233
00234 #ifdef UNDERLAY_OMNET
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 static cModule* SystemQueue__create() {
00253 return &SystemQueue::instance();
00254 }
00255
00256 EXECUTE_ON_STARTUP(SystemQueue__mod, modtypes.instance()->add(new cModuleType("SystemQueue","SystemQueue",(ModuleCreateFunc)SystemQueue__create));)
00257
00258 #endif
00259
00260 }}
00261
00262 #endif