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