// [License] // The Ariba-Underlay Copyright // // Copyright (c) 2008-2009, Institute of Telematics, Universität Karlsruhe (TH) // // Institute of Telematics // Universität Karlsruhe (TH) // Zirkel 2, 76128 Karlsruhe // Germany // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // The views and conclusions contained in the software and documentation // are those of the authors and should not be interpreted as representing // official policies, either expressed or implied, of the Institute of // Telematics. // [License] #ifndef SYSTEMQUEUE_H_ #define SYSTEMQUEUE_H_ // #include #include #include #include "SystemEvent.h" #include "SystemEventListener.h" #include "ariba/utility/logging/Logging.h" #include #include #include #include #include #include #include #include #include namespace ariba { namespace utility { using std::list; using boost::posix_time::ptime; /** * This class implements a simple system event queue to allow * a simulation of cooperative multitasking. It also allows * events to be scheduled from other tasks. This allows * dispatching asynchronous tasks. * * @author Christoph Mayer, Sebastian Mies */ /** XXX Mario Hock -- reworking the entire module **/ class SystemQueue : private boost::noncopyable { use_logging_h(SystemQueue); friend class EnterMethod; public: /** * Get the SystemQueue singleton instance. */ static SystemQueue& instance(); /** * This methods schedules a given event. * * @param The event to be scheduled * @param The delay in milli-seconds */ 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& function, uint32_t delay = 0 ); /** * Starts the processing and waiting for events. * Use cancel() to end system queue processing and * isEmpty() to check wheter the queue is empty. */ void run(); /** * Cancels the system queue and ends the processing after the * currently processed event is processed. * * This method is thread-safe. */ void cancel(); /** * Drop all queued events for that listener */ void dropAll( const SystemEventListener* mlistener); /** * Check wheter this queue has items or not. * * @return True, if this queue is empty. */ bool isEmpty(); /** * Is the system queue already started and running? * * @return True, if the system queue is running. */ bool isRunning(); protected: /** * Aqcuire the mutex */ void enterMethod(); /** * Leave the mutex */ void leaveMethod(); /** * Constructs a system queue. */ SystemQueue(); /** * Destroys the system queue. Beware that all events * are canceled */ ~SystemQueue(); /** * inner class of class SystemQueue: * * QueueThread -- the class the does the actual work */ private: typedef list EventQueue; //******************************************************** class QueueThread { friend class SystemQueue; public: QueueThread(); virtual ~QueueThread(); /// main loop -- called from boost::thread void operator()(); // 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(); private: EventQueue immediateEventsQ; EventQueue timedEventsQ; // boost::mutex queueMutex; // SystemEvent& currently_processed_event; ptime now; ptime next_deadline; boost::condition_variable system_queue_idle; boost::mutex queue_mutex; // boost::condition_variable itemsAvailable; DEPRECATED volatile bool running; volatile bool aborted; }; // 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* function_ptr = event.getData< boost::function0 >(); (*function_ptr)(); delete function_ptr; } }; FunctionCaller internal_function_caller; /// member variables of class SystemQueue private: QueueThread SysQ; boost::scoped_ptr sysq_thread; // volatile bool systemQueueRunning; }; // class SystemQueue }} // spovnet, common #endif /* SYSTEMQUEUE_H_ */