Chris@16
|
1 #ifndef BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED
|
Chris@16
|
2 #define BOOST_STATECHART_FIFO_SCHEDULER_HPP_INCLUDED
|
Chris@16
|
3 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
4 // Copyright 2002-2006 Andreas Huber Doenni
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See accompany-
|
Chris@16
|
6 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
8
|
Chris@16
|
9
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/statechart/event_base.hpp>
|
Chris@16
|
12 #include <boost/statechart/fifo_worker.hpp>
|
Chris@16
|
13 #include <boost/statechart/processor_container.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/intrusive_ptr.hpp>
|
Chris@16
|
16 #include <boost/noncopyable.hpp>
|
Chris@16
|
17 #include <boost/config.hpp> // BOOST_HAS_THREADS
|
Chris@16
|
18
|
Chris@16
|
19
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost
|
Chris@16
|
22 {
|
Chris@16
|
23 namespace statechart
|
Chris@16
|
24 {
|
Chris@16
|
25
|
Chris@16
|
26
|
Chris@16
|
27
|
Chris@16
|
28 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
29 template<
|
Chris@16
|
30 class FifoWorker = fifo_worker<>,
|
Chris@16
|
31 class Allocator = std::allocator< void > >
|
Chris@16
|
32 class fifo_scheduler : noncopyable
|
Chris@16
|
33 {
|
Chris@16
|
34 typedef processor_container<
|
Chris@16
|
35 fifo_scheduler, typename FifoWorker::work_item, Allocator > container;
|
Chris@16
|
36 public:
|
Chris@16
|
37 //////////////////////////////////////////////////////////////////////////
|
Chris@16
|
38 #ifdef BOOST_HAS_THREADS
|
Chris@16
|
39 fifo_scheduler( bool waitOnEmptyQueue = false ) :
|
Chris@16
|
40 worker_( waitOnEmptyQueue )
|
Chris@16
|
41 {
|
Chris@16
|
42 }
|
Chris@16
|
43 #endif
|
Chris@16
|
44
|
Chris@16
|
45 typedef typename container::processor_handle processor_handle;
|
Chris@16
|
46 typedef typename container::processor_context processor_context;
|
Chris@16
|
47
|
Chris@16
|
48 template< class Processor >
|
Chris@16
|
49 processor_handle create_processor()
|
Chris@16
|
50 {
|
Chris@16
|
51 processor_handle result;
|
Chris@16
|
52 work_item item =
|
Chris@16
|
53 container_.template create_processor< Processor >( result, *this );
|
Chris@16
|
54 worker_.queue_work_item( item );
|
Chris@16
|
55 return result;
|
Chris@16
|
56 }
|
Chris@16
|
57
|
Chris@16
|
58 template< class Processor, typename Arg1 >
|
Chris@16
|
59 processor_handle create_processor( Arg1 arg1 )
|
Chris@16
|
60 {
|
Chris@16
|
61 processor_handle result;
|
Chris@16
|
62 work_item item = container_.template create_processor< Processor >(
|
Chris@16
|
63 result, *this, arg1 );
|
Chris@16
|
64 worker_.queue_work_item( item );
|
Chris@16
|
65 return result;
|
Chris@16
|
66 }
|
Chris@16
|
67
|
Chris@16
|
68 template< class Processor, typename Arg1, typename Arg2 >
|
Chris@16
|
69 processor_handle create_processor( Arg1 arg1, Arg2 arg2 )
|
Chris@16
|
70 {
|
Chris@16
|
71 processor_handle result;
|
Chris@16
|
72 work_item item = container_.template create_processor< Processor >(
|
Chris@16
|
73 result, *this, arg1, arg2 );
|
Chris@16
|
74 worker_.queue_work_item( item );
|
Chris@16
|
75 return result;
|
Chris@16
|
76 }
|
Chris@16
|
77
|
Chris@16
|
78 template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
|
Chris@16
|
79 processor_handle create_processor( Arg1 arg1, Arg2 arg2, Arg3 arg3 )
|
Chris@16
|
80 {
|
Chris@16
|
81 processor_handle result;
|
Chris@16
|
82 work_item item = container_.template create_processor< Processor >(
|
Chris@16
|
83 result, *this, arg1, arg2, arg3 );
|
Chris@16
|
84 worker_.queue_work_item( item );
|
Chris@16
|
85 return result;
|
Chris@16
|
86 }
|
Chris@16
|
87
|
Chris@16
|
88 template<
|
Chris@16
|
89 class Processor, typename Arg1, typename Arg2,
|
Chris@16
|
90 typename Arg3, typename Arg4 >
|
Chris@16
|
91 processor_handle create_processor(
|
Chris@16
|
92 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
|
Chris@16
|
93 {
|
Chris@16
|
94 processor_handle result;
|
Chris@16
|
95 work_item item = container_.template create_processor< Processor >(
|
Chris@16
|
96 result, *this, arg1, arg2, arg3, arg4 );
|
Chris@16
|
97 worker_.queue_work_item( item );
|
Chris@16
|
98 return result;
|
Chris@16
|
99 }
|
Chris@16
|
100
|
Chris@16
|
101 template<
|
Chris@16
|
102 class Processor, typename Arg1, typename Arg2,
|
Chris@16
|
103 typename Arg3, typename Arg4, typename Arg5 >
|
Chris@16
|
104 processor_handle create_processor(
|
Chris@16
|
105 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
|
Chris@16
|
106 {
|
Chris@16
|
107 processor_handle result;
|
Chris@16
|
108 work_item item = container_.template create_processor< Processor >(
|
Chris@16
|
109 result, *this, arg1, arg2, arg3, arg4, arg5 );
|
Chris@16
|
110 worker_.queue_work_item( item );
|
Chris@16
|
111 return result;
|
Chris@16
|
112 }
|
Chris@16
|
113
|
Chris@16
|
114 template<
|
Chris@16
|
115 class Processor, typename Arg1, typename Arg2,
|
Chris@16
|
116 typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
|
Chris@16
|
117 processor_handle create_processor(
|
Chris@16
|
118 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
|
Chris@16
|
119 {
|
Chris@16
|
120 processor_handle result;
|
Chris@16
|
121 work_item item = container_.template create_processor< Processor >(
|
Chris@16
|
122 result, *this, arg1, arg2, arg3, arg4, arg5, arg6 );
|
Chris@16
|
123 worker_.queue_work_item( item );
|
Chris@16
|
124 return result;
|
Chris@16
|
125 }
|
Chris@16
|
126
|
Chris@16
|
127 void destroy_processor( const processor_handle & processor )
|
Chris@16
|
128 {
|
Chris@16
|
129 work_item item = container_.destroy_processor( processor );
|
Chris@16
|
130 worker_.queue_work_item( item );
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 void initiate_processor( const processor_handle & processor )
|
Chris@16
|
134 {
|
Chris@16
|
135 work_item item = container_.initiate_processor( processor );
|
Chris@16
|
136 worker_.queue_work_item( item );
|
Chris@16
|
137 }
|
Chris@16
|
138
|
Chris@16
|
139 void terminate_processor( const processor_handle & processor )
|
Chris@16
|
140 {
|
Chris@16
|
141 work_item item = container_.terminate_processor( processor );
|
Chris@16
|
142 worker_.queue_work_item( item );
|
Chris@16
|
143 }
|
Chris@16
|
144
|
Chris@16
|
145 typedef intrusive_ptr< const event_base > event_ptr_type;
|
Chris@16
|
146
|
Chris@16
|
147 void queue_event(
|
Chris@16
|
148 const processor_handle & processor, const event_ptr_type & pEvent )
|
Chris@16
|
149 {
|
Chris@16
|
150 work_item item = container_.queue_event( processor, pEvent );
|
Chris@16
|
151 worker_.queue_work_item( item );
|
Chris@16
|
152 }
|
Chris@16
|
153
|
Chris@16
|
154 typedef typename FifoWorker::work_item work_item;
|
Chris@16
|
155
|
Chris@16
|
156 // We take a non-const reference so that we can move (i.e. swap) the item
|
Chris@16
|
157 // into the queue, what avoids copying the (possibly heap-allocated)
|
Chris@16
|
158 // implementation object inside work_item.
|
Chris@16
|
159 void queue_work_item( work_item & item )
|
Chris@16
|
160 {
|
Chris@16
|
161 worker_.queue_work_item( item );
|
Chris@16
|
162 }
|
Chris@16
|
163
|
Chris@16
|
164 // Convenience overload so that temporary objects can be passed directly
|
Chris@16
|
165 // instead of having to create a work_item object first. Under most
|
Chris@16
|
166 // circumstances, this will lead to one unnecessary copy of the
|
Chris@16
|
167 // function implementation object.
|
Chris@16
|
168 void queue_work_item( const work_item & item )
|
Chris@16
|
169 {
|
Chris@16
|
170 worker_.queue_work_item( item );
|
Chris@16
|
171 }
|
Chris@16
|
172
|
Chris@16
|
173 void terminate()
|
Chris@16
|
174 {
|
Chris@16
|
175 worker_.terminate();
|
Chris@16
|
176 }
|
Chris@16
|
177
|
Chris@16
|
178 // Is not mutex-protected! Must only be called from the thread that also
|
Chris@16
|
179 // calls operator().
|
Chris@16
|
180 bool terminated() const
|
Chris@16
|
181 {
|
Chris@16
|
182 return worker_.terminated();
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185 unsigned long operator()( unsigned long maxEventCount = 0 )
|
Chris@16
|
186 {
|
Chris@16
|
187 return worker_( maxEventCount );
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 private:
|
Chris@16
|
191 //////////////////////////////////////////////////////////////////////////
|
Chris@16
|
192 container container_;
|
Chris@16
|
193 FifoWorker worker_;
|
Chris@16
|
194 };
|
Chris@16
|
195
|
Chris@16
|
196
|
Chris@16
|
197
|
Chris@16
|
198 } // namespace statechart
|
Chris@16
|
199 } // namespace boost
|
Chris@16
|
200
|
Chris@16
|
201
|
Chris@16
|
202
|
Chris@16
|
203 #endif
|