Index: source/ariba/utility/system/SystemQueue.h
===================================================================
--- source/ariba/utility/system/SystemQueue.h	(revision 12775)
+++ source/ariba/utility/system/SystemQueue.h	(revision 2378)
@@ -1,3 +1,3 @@
-// [License]
+// [Licence]
 // The Ariba-Underlay Copyright
 //
@@ -35,37 +35,34 @@
 // official policies, either expressed or implied, of the Institute of
 // Telematics.
-// [License]
+// [Licence]
 
 #ifndef SYSTEMQUEUE_H_
 #define SYSTEMQUEUE_H_
 
+#include <vector>
+#include <cassert>
 #include "SystemEvent.h"
 #include "SystemEventListener.h"
 #include "ariba/utility/logging/Logging.h"
-
-#include <cassert>
-#include <list>
-#include <vector>
-#include <queue>          // std::priority_queue
-#include <functional>     // std::greater
-
 #include <boost/date_time.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/scoped_ptr.hpp>
-
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/condition_variable.hpp>
-#include <boost/utility.hpp>
-#include <boost/bind.hpp>
-
-#include <boost/function.hpp>
+
+#ifdef UNDERLAY_OMNET
+  #include <csimplemodule.h>
+  #include <cmessage.h>
+  #include <macros.h>
+#else
+  #include <boost/thread/mutex.hpp>
+  #include <boost/thread/thread.hpp>
+  #include <boost/thread/condition_variable.hpp>
+  #include <boost/utility.hpp>
+  #include <boost/bind.hpp>
+#endif
+
+using std::vector;
+using boost::posix_time::ptime;
 
 namespace ariba {
 namespace utility {
-
-using std::list;
-using boost::posix_time::ptime;
-
 
 /**
@@ -77,16 +74,28 @@
  * @author Christoph Mayer, Sebastian Mies
  */
-/**  XXX Mario Hock  --  reworking the entire module  **/
-
-
-class SystemQueue : private boost::noncopyable
-{
+
+#ifndef UNDERLAY_OMNET
+class SystemQueue : private boost::noncopyable {
+#else
+class SystemQueue : public cSimpleModule {
+#endif
 	use_logging_h(SystemQueue);
-	friend class EnterMethod;
 public:
 	/**
 	 * Get the SystemQueue singleton instance.
 	 */
-	static SystemQueue& instance();
+	static SystemQueue& instance() {
+		static SystemQueue _inst;
+		return _inst;
+	}
+
+#ifdef UNDERLAY_OMNET
+	/**
+	 * Prevent deletion of this module
+	 * by implementing the virtual method
+	 * and doing nothing in it
+	 */
+	virtual void deleteModule(){}
+#endif
 
 	/**
@@ -97,13 +106,4 @@
 	 */
 	void scheduleEvent( const SystemEvent& event, uint32_t delay = 0 );
-	
-	/**
-	 * This method schedules a function call in the SystemQueue.
-	 * (Like scheduleEvent, but to be used with boost::bind.)
-	 * 
-	 * @param function: The function to be called [void function()]
-	 * @param The delay in milli-seconds
-	 */
-	void scheduleCall( const boost::function0<void>& function, uint32_t delay = 0 );
 
 	/**
@@ -117,37 +117,8 @@
 	 * Cancels the system queue and ends the processing after the
 	 * currently processed event is processed.
-     * 
-     * NOTE: Do not call this function from within a SystemQueue-Event.
-     *   Use SystemQueue::leave() instead.
 	 *
 	 * This method is thread-safe.
 	 */
 	void cancel();
-    
-    /**
-     * Like SystemQueue::cancel(), but may only be called from within a SystemQueue-Event.
-     * 
-     * NOTE: In this case some cleanup can not be made. -- If the SystemQueue is 
-     *   restarted, SystemQueue::cancel() must be called before SystemQueue::run()
-     *   can be called again.
-     */
-    void leave();
-    
-    /**
-     * Join the SystemQueue thread -- the current thread is blocked until the
-     * SystemQueue finishes.
-     * 
-     * NOTE: Use this only in combination with SystemQueue::leave()
-     * 
-     * [ There is a possible race condition with SystemQueue::cancel(), but 
-     *   SystemQueue::join() should not be used at the same time as 
-     *   SystemQueue::cancel() anyway. (SystemQueue::leave() is fine, though.)
-     */
-    void join();
-
-	/**
-	 * Drop all queued events for that listener
-	 */
-	void dropAll( const SystemEventListener* mlistener);
 
 	/**
@@ -161,27 +132,9 @@
 	 * Is the system queue already started and running?
 	 *
-	 * @return TRUE, if the system queue is running. | FALSE otherwise
+	 * @return True, if the system queue is running.
 	 */
 	bool isRunning();
-    
-    /**
-     *  NOTE: This function is for debugging and asserts only!!
-     * 
-     *  @return TRUE if called from the SysQ thread (from inside a SystemEvent)
-     *          | FALSE if it's called from another thread
-     */
-    bool am_I_in_the_SysQ_thread();
 
 protected:
-
-	/**
-	 * Aqcuire the mutex
-	 */
-	void enterMethod();
-
-	/**
-	 * Leave the mutex
-	 */
-	void leaveMethod();
 
 	/**
@@ -195,95 +148,100 @@
 	 */
 	~SystemQueue();
-	
-
-/**
- *  inner class of class SystemQueue:
- * 
- *  QueueThread  --  the class the does the actual work
- */
+
+#ifdef UNDERLAY_OMNET
+	virtual void handleMessage( cMessage* msg );
+#endif
+
 private:
 
-typedef list<SystemEvent> EventQueue;
-typedef std::priority_queue<SystemEvent, 
-                            std::vector<SystemEvent>,  // [ TODO is vector the best underlay? ]
-                            std::greater<SystemEvent> > PriorityEventQueue;
-
-	//********************************************************
-
-	class QueueThread
-	{
-        friend class SystemQueue;
-        
+#ifndef UNDERLAY_OMNET
+	typedef vector<SystemEvent> EventQueue;
+
+	//********************************************************
+
+	class QueueThread {
 	public:
-		QueueThread();
+		QueueThread(QueueThread* _transferQueue = NULL);
 		virtual ~QueueThread();
-        
-        /// main loop -- called from boost::thread
-        void operator()();
-        
-// 		void run();
+		void run();
 		void cancel();
 		bool isEmpty();
-		void insert( SystemEvent& event, uint32_t delay );
-		void enter();
-		void leave();
-		void dropAll( const SystemEventListener* mlistener);
-        bool isRunning();
-
-    private:
-        
-        /// main loop functions
-        void run_immediate_event();
-        void check_timed_queue();
-        void wait_for_next_deadline();
-        
-        /// makes sure that always the same clock is used
-        ptime get_clock();
-        
-        
+		void insert( const SystemEvent& event, uint32_t delay );
+
+	protected:
+		virtual void onItemInserted( const SystemEvent& event ) = 0;
+		virtual void onNextQueueItem( const SystemEvent& event ) = 0;
+		QueueThread* transferQueue;
+		EventQueue eventsQueue;
+		boost::mutex queueMutex;
 	private:
-        EventQueue immediateEventsQ;
-        PriorityEventQueue timedEventsQ;
-        
-        boost::condition_variable system_queue_idle;
-        boost::mutex queue_mutex;
-
-        bool processing_event;
-        
+		boost::thread* queueThread;
+		static void threadFunc( QueueThread* obj );
+		boost::condition_variable itemsAvailable;
 		volatile bool running;
-        volatile bool aborted;
-        volatile bool unclean;
 	}; // class QueueThread
 
-	
-/// inner class of class SystemQueue
-private:
-    /**
-     * This inner class handles the function-call events.
-     * @see SystemQueue::scheduleCall
-     */
-    class FunctionCaller  :  public SystemEventListener
-    {
-        void handleSystemEvent(const SystemEvent& event)
-        {
-            boost::function0<void>* function_ptr = event.getData< boost::function0<void> >();
-            (*function_ptr)();
-            delete function_ptr;
-        }
-    };
-
-    FunctionCaller internal_function_caller;
-    
-    
-    
-    /// member variables of class SystemQueue
-private:
-    boost::scoped_ptr<QueueThread> SysQ;
-    boost::scoped_ptr<boost::thread> sysq_thread;
-    
-//  volatile bool systemQueueRunning;
+	//********************************************************
+
+	class QueueThreadDirect : public QueueThread {
+	public:
+		QueueThreadDirect();
+		~QueueThreadDirect();
+	protected:
+		virtual void onItemInserted( const SystemEvent& event );
+		virtual void onNextQueueItem( const SystemEvent& event );
+	}; // class QueueThreadDirect
+
+	//********************************************************
+
+	class QueueThreadDelay : public QueueThread {
+	public:
+		QueueThreadDelay(QueueThread* _transferQueue = NULL);
+		~QueueThreadDelay();
+	protected:
+		virtual void onItemInserted( const SystemEvent& event );
+		virtual void onNextQueueItem( const SystemEvent& event );
+	private:
+		volatile bool isSleeping;
+		ptime sleepStart;
+		boost::mutex sleepMutex;
+		boost::condition_variable sleepCond;
+	}; // class QueueThreadDelay
+
+	//********************************************************
+
+	QueueThreadDirect directScheduler;
+	QueueThreadDelay delayScheduler;
+	volatile bool systemQueueRunning;
+#endif
 
 }; // class SystemQueue
 
+#ifdef UNDERLAY_OMNET
+
+	//
+	// the system queue must be a singleton in simulations, too.
+	// and to include it in the simulation the module is defined
+	// as submodule in every SpoVNet host. Therefore we hack the
+	// Define_Module (see omnet/includes/macros.h) the way we need
+	// it with our singleton ...
+	//
+	// this is the macro definition from macros.h
+	//
+	// #define Define_Module(CLASSNAME) \
+	//   static cModule *CLASSNAME##__create() {return new CLASSNAME();} \
+	//   EXECUTE_ON_STARTUP(CLASSNAME##__mod, modtypes.instance()->add(new cModuleType(#CLASSNAME,#CLASSNAME,(ModuleCreateFunc)CLASSNAME##__create));)
+	//
+	// and this is how we do it :)
+	//
+
+  	static cModule* SystemQueue__create() {
+		return &SystemQueue::instance();
+	}
+
+ 	EXECUTE_ON_STARTUP(SystemQueue__mod, modtypes.instance()->add(new cModuleType("SystemQueue","SystemQueue",(ModuleCreateFunc)SystemQueue__create));)
+
+#endif
+
 }} // spovnet, common
 
