Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:00:51

0001 #ifndef BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED
0002 #define BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED
0003 //////////////////////////////////////////////////////////////////////////////
0004 // Copyright 2002-2006 Andreas Huber Doenni
0005 // Distributed under the Boost Software License, Version 1.0. (See accompany-
0006 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //////////////////////////////////////////////////////////////////////////////
0008 
0009 
0010 
0011 #include <boost/statechart/event_base.hpp>
0012 #include <boost/statechart/fifo_worker.hpp>
0013 #include <boost/statechart/processor_container.hpp>
0014 
0015 #include <boost/intrusive_ptr.hpp>
0016 #include <boost/noncopyable.hpp>
0017 #include <boost/config.hpp> // BOOST_HAS_THREADS
0018 
0019 
0020 
0021 namespace boost
0022 {
0023 namespace statechart
0024 {
0025 
0026 
0027 
0028 //////////////////////////////////////////////////////////////////////////////
0029 template<
0030   class FifoWorker = fifo_worker<>,
0031   class Allocator = std::allocator< none > >
0032 class fifo_scheduler : noncopyable
0033 {
0034   typedef processor_container<
0035     fifo_scheduler, typename FifoWorker::work_item, Allocator > container;
0036   public:
0037     //////////////////////////////////////////////////////////////////////////
0038     #ifdef BOOST_HAS_THREADS
0039     fifo_scheduler( bool waitOnEmptyQueue = false ) :
0040       worker_( waitOnEmptyQueue )
0041     {
0042     }
0043     #endif
0044 
0045     typedef typename container::processor_handle processor_handle;
0046     typedef typename container::processor_context processor_context;
0047 
0048     template< class Processor >
0049     processor_handle create_processor()
0050     {
0051       processor_handle result;
0052       work_item item =
0053         container_.template create_processor< Processor >( result, *this );
0054       worker_.queue_work_item( item );
0055       return result;
0056     }
0057 
0058     template< class Processor, typename Arg1 >
0059     processor_handle create_processor( Arg1 arg1 )
0060     {
0061       processor_handle result;
0062       work_item item = container_.template create_processor< Processor >(
0063         result, *this, arg1 );
0064       worker_.queue_work_item( item );
0065       return result;
0066     }
0067 
0068     template< class Processor, typename Arg1, typename Arg2 >
0069     processor_handle create_processor( Arg1 arg1, Arg2 arg2 )
0070     {
0071       processor_handle result;
0072       work_item item = container_.template create_processor< Processor >(
0073         result, *this, arg1, arg2 );
0074       worker_.queue_work_item( item );
0075       return result;
0076     }
0077 
0078     template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
0079     processor_handle create_processor( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
0080     {
0081       processor_handle result;
0082       work_item item = container_.template create_processor< Processor >(
0083         result, *this, arg1, arg2, arg3 );
0084       worker_.queue_work_item( item );
0085       return result;
0086     }
0087 
0088     template<
0089       class Processor, typename Arg1, typename Arg2,
0090       typename Arg3, typename Arg4 >
0091     processor_handle create_processor(
0092       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
0093     {
0094       processor_handle result;
0095       work_item item = container_.template create_processor< Processor >(
0096         result, *this, arg1, arg2, arg3, arg4 );
0097       worker_.queue_work_item( item );
0098       return result;
0099     }
0100 
0101     template<
0102       class Processor, typename Arg1, typename Arg2,
0103       typename Arg3, typename Arg4, typename Arg5 >
0104     processor_handle create_processor(
0105       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
0106     {
0107       processor_handle result;
0108       work_item item = container_.template create_processor< Processor >(
0109         result, *this, arg1, arg2, arg3, arg4, arg5 );
0110       worker_.queue_work_item( item );
0111       return result;
0112     }
0113 
0114     template<
0115       class Processor, typename Arg1, typename Arg2,
0116       typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
0117     processor_handle create_processor(
0118       Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
0119     {
0120       processor_handle result;
0121       work_item item = container_.template create_processor< Processor >(
0122         result, *this, arg1, arg2, arg3, arg4, arg5, arg6 );
0123       worker_.queue_work_item( item );
0124       return result;
0125     }
0126 
0127     void destroy_processor( const processor_handle & processor )
0128     {
0129       work_item item = container_.destroy_processor( processor );
0130       worker_.queue_work_item( item );
0131     }
0132 
0133     void initiate_processor( const processor_handle & processor )
0134     {
0135       work_item item = container_.initiate_processor( processor );
0136       worker_.queue_work_item( item );
0137     }
0138 
0139     void terminate_processor( const processor_handle & processor )
0140     {
0141       work_item item = container_.terminate_processor( processor );
0142       worker_.queue_work_item( item );
0143     }
0144 
0145     typedef intrusive_ptr< const event_base > event_ptr_type;
0146 
0147     void queue_event(
0148       const processor_handle & processor, const event_ptr_type & pEvent )
0149     {
0150       work_item item = container_.queue_event( processor, pEvent );
0151       worker_.queue_work_item( item );
0152     }
0153 
0154     typedef typename FifoWorker::work_item work_item;
0155 
0156     // We take a non-const reference so that we can move (i.e. swap) the item
0157     // into the queue, what avoids copying the (possibly heap-allocated)
0158     // implementation object inside work_item.
0159     void queue_work_item( work_item & item )
0160     {
0161       worker_.queue_work_item( item );
0162     }
0163 
0164     // Convenience overload so that temporary objects can be passed directly
0165     // instead of having to create a work_item object first. Under most
0166     // circumstances, this will lead to one unnecessary copy of the
0167     // function implementation object.
0168     void queue_work_item( const work_item & item )
0169     {
0170       worker_.queue_work_item( item );
0171     }
0172 
0173     void terminate()
0174     {
0175       worker_.terminate();
0176     }
0177 
0178     // Is not mutex-protected! Must only be called from the thread that also
0179     // calls operator().
0180     bool terminated() const
0181     {
0182       return worker_.terminated();
0183     }
0184 
0185     unsigned long operator()( unsigned long maxEventCount = 0 )
0186     {
0187       return worker_( maxEventCount );
0188     }
0189 
0190   private:
0191     //////////////////////////////////////////////////////////////////////////
0192     container container_;
0193     FifoWorker worker_;
0194 };
0195 
0196 
0197 
0198 } // namespace statechart
0199 } // namespace boost
0200 
0201 
0202 
0203 #endif