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 use_logging_h(SystemQueue);
00083 public:
00087 static SystemQueue& instance() {
00088 static SystemQueue _inst;
00089 return _inst;
00090 }
00091
00092 #ifdef UNDERLAY_OMNET
00093
00098 virtual void deleteModule(){}
00099 #endif
00100
00107 void scheduleEvent( const SystemEvent& event, uint32_t delay = 0 );
00108
00114 void run();
00115
00122 void cancel();
00123
00129 bool isEmpty();
00130
00136 bool isRunning();
00137
00138 protected:
00139
00143 SystemQueue();
00144
00149 ~SystemQueue();
00150
00151 #ifdef UNDERLAY_OMNET
00152 virtual void handleMessage( cMessage* msg );
00153 #endif
00154
00155 private:
00156
00157 #ifndef UNDERLAY_OMNET
00158 typedef vector<SystemEvent> EventQueue;
00159
00160
00161
00162 class QueueThread {
00163 public:
00164 QueueThread(QueueThread* _transferQueue = NULL);
00165 virtual ~QueueThread();
00166 void run();
00167 void cancel();
00168 bool isEmpty();
00169 void insert( const SystemEvent& event, uint32_t delay );
00170
00171 protected:
00172 virtual void onItemInserted( const SystemEvent& event ) = 0;
00173 virtual void onNextQueueItem( const SystemEvent& event ) = 0;
00174 QueueThread* transferQueue;
00175 EventQueue eventsQueue;
00176 boost::mutex queueMutex;
00177 private:
00178 boost::thread* queueThread;
00179 static void threadFunc( QueueThread* obj );
00180 boost::condition_variable itemsAvailable;
00181 volatile bool running;
00182 };
00183
00184
00185
00186 class QueueThreadDirect : public QueueThread {
00187 public:
00188 QueueThreadDirect();
00189 ~QueueThreadDirect();
00190 protected:
00191 virtual void onItemInserted( const SystemEvent& event );
00192 virtual void onNextQueueItem( const SystemEvent& event );
00193 };
00194
00195
00196
00197 class QueueThreadDelay : public QueueThread {
00198 public:
00199 QueueThreadDelay(QueueThread* _transferQueue = NULL);
00200 ~QueueThreadDelay();
00201 protected:
00202 virtual void onItemInserted( const SystemEvent& event );
00203 virtual void onNextQueueItem( const SystemEvent& event );
00204 private:
00205 volatile bool isSleeping;
00206 ptime sleepStart;
00207 boost::mutex sleepMutex;
00208 boost::condition_variable sleepCond;
00209 };
00210
00211
00212
00213 QueueThreadDirect directScheduler;
00214 QueueThreadDelay delayScheduler;
00215 volatile bool systemQueueRunning;
00216 #endif
00217
00218 };
00219
00220 #ifdef UNDERLAY_OMNET
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 static cModule* SystemQueue__create() {
00239 return &SystemQueue::instance();
00240 }
00241
00242 EXECUTE_ON_STARTUP(SystemQueue__mod, modtypes.instance()->add(new cModuleType("SystemQueue","SystemQueue",(ModuleCreateFunc)SystemQueue__create));)
00243
00244 #endif
00245
00246 }}
00247
00248 #endif