Chris@16: #ifndef BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED Chris@16: #define BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Copyright 2002-2006 Andreas Huber Doenni Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompany- Chris@16: // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include // BOOST_HAS_THREADS Chris@16: Chris@16: Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace statechart Chris@16: { Chris@16: Chris@16: Chris@16: Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: template< Chris@16: class FifoWorker = fifo_worker<>, Chris@16: class Allocator = std::allocator< void > > Chris@16: class fifo_scheduler : noncopyable Chris@16: { Chris@16: typedef processor_container< Chris@16: fifo_scheduler, typename FifoWorker::work_item, Allocator > container; Chris@16: public: Chris@16: ////////////////////////////////////////////////////////////////////////// Chris@16: #ifdef BOOST_HAS_THREADS Chris@16: fifo_scheduler( bool waitOnEmptyQueue = false ) : Chris@16: worker_( waitOnEmptyQueue ) Chris@16: { Chris@16: } Chris@16: #endif Chris@16: Chris@16: typedef typename container::processor_handle processor_handle; Chris@16: typedef typename container::processor_context processor_context; Chris@16: Chris@16: template< class Processor > Chris@16: processor_handle create_processor() Chris@16: { Chris@16: processor_handle result; Chris@16: work_item item = Chris@16: container_.template create_processor< Processor >( result, *this ); Chris@16: worker_.queue_work_item( item ); Chris@16: return result; Chris@16: } Chris@16: Chris@16: template< class Processor, typename Arg1 > Chris@16: processor_handle create_processor( Arg1 arg1 ) Chris@16: { Chris@16: processor_handle result; Chris@16: work_item item = container_.template create_processor< Processor >( Chris@16: result, *this, arg1 ); Chris@16: worker_.queue_work_item( item ); Chris@16: return result; Chris@16: } Chris@16: Chris@16: template< class Processor, typename Arg1, typename Arg2 > Chris@16: processor_handle create_processor( Arg1 arg1, Arg2 arg2 ) Chris@16: { Chris@16: processor_handle result; Chris@16: work_item item = container_.template create_processor< Processor >( Chris@16: result, *this, arg1, arg2 ); Chris@16: worker_.queue_work_item( item ); Chris@16: return result; Chris@16: } Chris@16: Chris@16: template< class Processor, typename Arg1, typename Arg2, typename Arg3 > Chris@16: processor_handle create_processor( Arg1 arg1, Arg2 arg2, Arg3 arg3 ) Chris@16: { Chris@16: processor_handle result; Chris@16: work_item item = container_.template create_processor< Processor >( Chris@16: result, *this, arg1, arg2, arg3 ); Chris@16: worker_.queue_work_item( item ); Chris@16: return result; Chris@16: } Chris@16: Chris@16: template< Chris@16: class Processor, typename Arg1, typename Arg2, Chris@16: typename Arg3, typename Arg4 > Chris@16: processor_handle create_processor( Chris@16: Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 ) Chris@16: { Chris@16: processor_handle result; Chris@16: work_item item = container_.template create_processor< Processor >( Chris@16: result, *this, arg1, arg2, arg3, arg4 ); Chris@16: worker_.queue_work_item( item ); Chris@16: return result; Chris@16: } Chris@16: Chris@16: template< Chris@16: class Processor, typename Arg1, typename Arg2, Chris@16: typename Arg3, typename Arg4, typename Arg5 > Chris@16: processor_handle create_processor( Chris@16: Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 ) Chris@16: { Chris@16: processor_handle result; Chris@16: work_item item = container_.template create_processor< Processor >( Chris@16: result, *this, arg1, arg2, arg3, arg4, arg5 ); Chris@16: worker_.queue_work_item( item ); Chris@16: return result; Chris@16: } Chris@16: Chris@16: template< Chris@16: class Processor, typename Arg1, typename Arg2, Chris@16: typename Arg3, typename Arg4, typename Arg5, typename Arg6 > Chris@16: processor_handle create_processor( Chris@16: Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 ) Chris@16: { Chris@16: processor_handle result; Chris@16: work_item item = container_.template create_processor< Processor >( Chris@16: result, *this, arg1, arg2, arg3, arg4, arg5, arg6 ); Chris@16: worker_.queue_work_item( item ); Chris@16: return result; Chris@16: } Chris@16: Chris@16: void destroy_processor( const processor_handle & processor ) Chris@16: { Chris@16: work_item item = container_.destroy_processor( processor ); Chris@16: worker_.queue_work_item( item ); Chris@16: } Chris@16: Chris@16: void initiate_processor( const processor_handle & processor ) Chris@16: { Chris@16: work_item item = container_.initiate_processor( processor ); Chris@16: worker_.queue_work_item( item ); Chris@16: } Chris@16: Chris@16: void terminate_processor( const processor_handle & processor ) Chris@16: { Chris@16: work_item item = container_.terminate_processor( processor ); Chris@16: worker_.queue_work_item( item ); Chris@16: } Chris@16: Chris@16: typedef intrusive_ptr< const event_base > event_ptr_type; Chris@16: Chris@16: void queue_event( Chris@16: const processor_handle & processor, const event_ptr_type & pEvent ) Chris@16: { Chris@16: work_item item = container_.queue_event( processor, pEvent ); Chris@16: worker_.queue_work_item( item ); Chris@16: } Chris@16: Chris@16: typedef typename FifoWorker::work_item work_item; Chris@16: Chris@16: // We take a non-const reference so that we can move (i.e. swap) the item Chris@16: // into the queue, what avoids copying the (possibly heap-allocated) Chris@16: // implementation object inside work_item. Chris@16: void queue_work_item( work_item & item ) Chris@16: { Chris@16: worker_.queue_work_item( item ); Chris@16: } Chris@16: Chris@16: // Convenience overload so that temporary objects can be passed directly Chris@16: // instead of having to create a work_item object first. Under most Chris@16: // circumstances, this will lead to one unnecessary copy of the Chris@16: // function implementation object. Chris@16: void queue_work_item( const work_item & item ) Chris@16: { Chris@16: worker_.queue_work_item( item ); Chris@16: } Chris@16: Chris@16: void terminate() Chris@16: { Chris@16: worker_.terminate(); Chris@16: } Chris@16: Chris@16: // Is not mutex-protected! Must only be called from the thread that also Chris@16: // calls operator(). Chris@16: bool terminated() const Chris@16: { Chris@16: return worker_.terminated(); Chris@16: } Chris@16: Chris@16: unsigned long operator()( unsigned long maxEventCount = 0 ) Chris@16: { Chris@16: return worker_( maxEventCount ); Chris@16: } Chris@16: Chris@16: private: Chris@16: ////////////////////////////////////////////////////////////////////////// Chris@16: container container_; Chris@16: FifoWorker worker_; Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: } // namespace statechart Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: Chris@16: #endif