]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/statechart/processor_container.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / statechart / processor_container.hpp
CommitLineData
7c673cae
FG
1#ifndef BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
2#define BOOST_STATECHART_PROCESSOR_CONTAINER_HPP_INCLUDED
3//////////////////////////////////////////////////////////////////////////////
4// Copyright 2002-2008 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/event_processor.hpp>
13
14#include <boost/assert.hpp>
15#include <boost/ref.hpp>
16#include <boost/noncopyable.hpp>
17#include <boost/intrusive_ptr.hpp>
18#include <boost/shared_ptr.hpp>
19#include <boost/weak_ptr.hpp>
20#include <boost/bind.hpp>
21#include <boost/config.hpp> // BOOST_INTEL
22
23#include <boost/detail/workaround.hpp>
24#include <boost/detail/allocator_utilities.hpp>
25
26#include <set>
11fdf7f2 27#include <memory> // std::allocator, std::unique_ptr
7c673cae
FG
28
29
30
31namespace boost
32{
33namespace statechart
34{
35namespace detail
36{
37 template<bool IsReferenceWrapper>
38 struct unwrap_impl
39 {
40 template< typename T >
41 struct apply { typedef T type; };
42 };
43
44 template<>
45 struct unwrap_impl<true>
46 {
47 template< typename T >
48 struct apply { typedef typename T::type & type; };
49 };
50
51 template<typename T>
52 struct unwrap
53 {
54 typedef typename unwrap_impl<
55 is_reference_wrapper< T >::value >::template apply< T >::type type;
56 };
57}
58
59
60template<
61 class Scheduler,
62 class WorkItem,
92f5a8d4 63 class Allocator = std::allocator< none > >
7c673cae
FG
64class processor_container : noncopyable
65{
66 typedef event_processor< Scheduler > processor_base_type;
11fdf7f2
TL
67#ifdef BOOST_NO_AUTO_PTR
68 typedef std::unique_ptr< processor_base_type > processor_holder_type;
69#else
7c673cae 70 typedef std::auto_ptr< processor_base_type > processor_holder_type;
11fdf7f2 71#endif
7c673cae
FG
72 typedef shared_ptr< processor_holder_type > processor_holder_ptr_type;
73
74 public:
75 //////////////////////////////////////////////////////////////////////////
76 typedef weak_ptr< processor_holder_type > processor_handle;
77
78 class processor_context
79 {
80 processor_context(
81 Scheduler & scheduler, const processor_handle & handle
82 ) :
83 scheduler_( scheduler ),
84 handle_( handle )
85 {
86 }
87
88 #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
89 public:
90 // for some reason Intel 8.0 seems to think that the following functions
91 // are inaccessible from event_processor<>::event_processor
92 #endif
93
94 Scheduler & my_scheduler() const { return scheduler_; }
95 const processor_handle & my_handle() const { return handle_; }
96
97 #if BOOST_WORKAROUND( BOOST_INTEL, BOOST_TESTED_AT( 800 ) )
98 private:
99 #endif
100
101 // avoids C4512 (assignment operator could not be generated)
102 processor_context & operator=( const processor_context & );
103
104 Scheduler & scheduler_;
105 const processor_handle handle_;
106
107 friend class processor_container;
108 friend class event_processor< Scheduler >;
109 };
110
111 template< class Processor >
112 WorkItem create_processor( processor_handle & handle, Scheduler & scheduler )
113 {
114 processor_holder_ptr_type pProcessor = make_processor_holder();
115 handle = pProcessor;
116 typedef void ( processor_container::*impl_fun_ptr )(
117 const processor_holder_ptr_type &, const processor_context & );
118 impl_fun_ptr pImpl =
119 &processor_container::template create_processor_impl0< Processor >;
120 return WorkItem(
121 boost::bind( pImpl, this, pProcessor,
122 processor_context( scheduler, handle ) ),
123 Allocator() );
124 }
125
126 template< class Processor, typename Arg1 >
127 WorkItem create_processor(
128 processor_handle & handle, Scheduler & scheduler, Arg1 arg1 )
129 {
130 processor_holder_ptr_type pProcessor = make_processor_holder();
131 handle = pProcessor;
132 typedef typename detail::unwrap< Arg1 >::type arg1_type;
133 typedef void ( processor_container::*impl_fun_ptr )(
134 const processor_holder_ptr_type &, const processor_context &,
135 arg1_type );
136 impl_fun_ptr pImpl =
137 &processor_container::template create_processor_impl1<
138 Processor, arg1_type >;
139 return WorkItem(
140 boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
141 arg1 ),
142 Allocator() );
143 }
144
145 template< class Processor, typename Arg1, typename Arg2 >
146 WorkItem create_processor(
147 processor_handle & handle, Scheduler & scheduler, Arg1 arg1, Arg2 arg2 )
148 {
149 processor_holder_ptr_type pProcessor = make_processor_holder();
150 handle = pProcessor;
151 typedef typename detail::unwrap< Arg1 >::type arg1_type;
152 typedef typename detail::unwrap< Arg2 >::type arg2_type;
153 typedef void ( processor_container::*impl_fun_ptr )(
154 const processor_holder_ptr_type &, const processor_context &,
155 arg1_type, arg2_type );
156 impl_fun_ptr pImpl =
157 &processor_container::template create_processor_impl2<
158 Processor, arg1_type, arg2_type >;
159 return WorkItem(
160 boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
161 arg1, arg2 ),
162 Allocator() );
163 }
164
165 template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
166 WorkItem create_processor(
167 processor_handle & handle, Scheduler & scheduler,
168 Arg1 arg1, Arg2 arg2, Arg3 arg3 )
169 {
170 processor_holder_ptr_type pProcessor = make_processor_holder();
171 handle = pProcessor;
172 typedef typename detail::unwrap< Arg1 >::type arg1_type;
173 typedef typename detail::unwrap< Arg2 >::type arg2_type;
174 typedef typename detail::unwrap< Arg3 >::type arg3_type;
175 typedef void ( processor_container::*impl_fun_ptr )(
176 const processor_holder_ptr_type &, const processor_context &,
177 arg1_type, arg2_type, arg3_type );
178 impl_fun_ptr pImpl =
179 &processor_container::template create_processor_impl3<
180 Processor, arg1_type, arg2_type, arg3_type >;
181 return WorkItem(
182 boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
183 arg1, arg2, arg3 ),
184 Allocator() );
185 }
186
187 template<
188 class Processor, typename Arg1, typename Arg2,
189 typename Arg3, typename Arg4 >
190 WorkItem create_processor(
191 processor_handle & handle, Scheduler & scheduler,
192 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
193 {
194 processor_holder_ptr_type pProcessor = make_processor_holder();
195 handle = pProcessor;
196 typedef typename detail::unwrap< Arg1 >::type arg1_type;
197 typedef typename detail::unwrap< Arg2 >::type arg2_type;
198 typedef typename detail::unwrap< Arg3 >::type arg3_type;
199 typedef typename detail::unwrap< Arg4 >::type arg4_type;
200 typedef void ( processor_container::*impl_fun_ptr )(
201 const processor_holder_ptr_type &, const processor_context &,
202 arg1_type, arg2_type, arg3_type, arg4_type );
203 impl_fun_ptr pImpl =
204 &processor_container::template create_processor_impl4<
205 Processor, arg1_type, arg2_type, arg3_type, arg4_type >;
206 return WorkItem(
207 boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
208 arg1, arg2, arg3, arg4 ),
209 Allocator() );
210 }
211
212 template<
213 class Processor, typename Arg1, typename Arg2,
214 typename Arg3, typename Arg4, typename Arg5 >
215 WorkItem create_processor(
216 processor_handle & handle, Scheduler & scheduler,
217 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
218 {
219 processor_holder_ptr_type pProcessor = make_processor_holder();
220 handle = pProcessor;
221 typedef typename detail::unwrap< Arg1 >::type arg1_type;
222 typedef typename detail::unwrap< Arg2 >::type arg2_type;
223 typedef typename detail::unwrap< Arg3 >::type arg3_type;
224 typedef typename detail::unwrap< Arg4 >::type arg4_type;
225 typedef typename detail::unwrap< Arg5 >::type arg5_type;
226 typedef void ( processor_container::*impl_fun_ptr )(
227 const processor_holder_ptr_type &, const processor_context &,
228 arg1_type, arg2_type, arg3_type, arg4_type, arg5_type );
229 impl_fun_ptr pImpl =
230 &processor_container::template create_processor_impl5<
231 Processor, arg1_type, arg2_type, arg3_type, arg4_type, arg5_type >;
232 return WorkItem(
233 boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
234 arg1, arg2, arg3, arg4, arg5 ),
235 Allocator() );
236 }
237
238 template<
239 class Processor, typename Arg1, typename Arg2,
240 typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
241 WorkItem create_processor(
242 processor_handle & handle, Scheduler & scheduler,
243 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
244 {
245 processor_holder_ptr_type pProcessor = make_processor_holder();
246 handle = pProcessor;
247 typedef typename detail::unwrap< Arg1 >::type arg1_type;
248 typedef typename detail::unwrap< Arg2 >::type arg2_type;
249 typedef typename detail::unwrap< Arg3 >::type arg3_type;
250 typedef typename detail::unwrap< Arg4 >::type arg4_type;
251 typedef typename detail::unwrap< Arg5 >::type arg5_type;
252 typedef typename detail::unwrap< Arg6 >::type arg6_type;
253 typedef void ( processor_container::*impl_fun_ptr )(
254 const processor_holder_ptr_type &, const processor_context &,
255 arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type );
256 impl_fun_ptr pImpl =
257 &processor_container::template create_processor_impl6<
258 Processor,
259 arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type >;
260 return WorkItem(
261 boost::bind( pImpl, this, pProcessor, processor_context( scheduler, handle ),
262 arg1, arg2, arg3, arg4, arg5, arg6 ),
263 Allocator() );
264 }
265
266 WorkItem destroy_processor( const processor_handle & processor )
267 {
268 return WorkItem(
269 boost::bind( &processor_container::destroy_processor_impl, this, processor ),
270 Allocator() );
271 }
272
273 WorkItem initiate_processor( const processor_handle & processor )
274 {
275 return WorkItem(
276 boost::bind( &processor_container::initiate_processor_impl, this,
277 processor ),
278 Allocator() );
279 }
280
281 WorkItem terminate_processor( const processor_handle & processor )
282 {
283 return WorkItem(
284 boost::bind( &processor_container::terminate_processor_impl, this,
285 processor ),
286 Allocator() );
287 }
288
289 typedef intrusive_ptr< const event_base > event_ptr_type;
290
291 WorkItem queue_event(
292 const processor_handle & processor, const event_ptr_type & pEvent )
293 {
294 BOOST_ASSERT( pEvent.get() != 0 );
295
296 return WorkItem(
297 boost::bind( &processor_container::queue_event_impl, this, processor,
298 pEvent ),
299 Allocator() );
300 }
301
302 private:
303 //////////////////////////////////////////////////////////////////////////
304 processor_holder_ptr_type make_processor_holder()
305 {
306 return processor_holder_ptr_type( new processor_holder_type() );
307 }
308
309 template< class Processor >
310 void create_processor_impl0(
311 const processor_holder_ptr_type & pProcessor,
312 const processor_context & context )
313 {
314 processorSet_.insert( pProcessor );
11fdf7f2 315 *pProcessor = processor_holder_type( new Processor( context ) );
7c673cae
FG
316 }
317
318 template< class Processor, typename Arg1 >
319 void create_processor_impl1(
320 const processor_holder_ptr_type & pProcessor,
321 const processor_context & context, Arg1 arg1 )
322 {
323 processorSet_.insert( pProcessor );
11fdf7f2 324 *pProcessor = processor_holder_type( new Processor( context, arg1 ) );
7c673cae
FG
325 }
326
327 template< class Processor, typename Arg1, typename Arg2 >
328 void create_processor_impl2(
329 const processor_holder_ptr_type & pProcessor,
330 const processor_context & context, Arg1 arg1, Arg2 arg2 )
331 {
332 processorSet_.insert( pProcessor );
11fdf7f2 333 *pProcessor = processor_holder_type( new Processor( context, arg1, arg2 ) );
7c673cae
FG
334 }
335
336 template< class Processor, typename Arg1, typename Arg2, typename Arg3 >
337 void create_processor_impl3(
338 const processor_holder_ptr_type & pProcessor,
339 const processor_context & context, Arg1 arg1, Arg2 arg2, Arg3 arg3 )
340 {
341 processorSet_.insert( pProcessor );
11fdf7f2 342 *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3 ) );
7c673cae
FG
343 }
344
345 template<
346 class Processor, typename Arg1, typename Arg2,
347 typename Arg3, typename Arg4 >
348 void create_processor_impl4(
349 const processor_holder_ptr_type & pProcessor,
350 const processor_context & context,
351 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4 )
352 {
353 processorSet_.insert( pProcessor );
11fdf7f2 354 *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3, arg4 ) );
7c673cae
FG
355 }
356
357 template<
358 class Processor, typename Arg1, typename Arg2,
359 typename Arg3, typename Arg4, typename Arg5 >
360 void create_processor_impl5(
361 const processor_holder_ptr_type & pProcessor,
362 const processor_context & context,
363 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5 )
364 {
365 processorSet_.insert( pProcessor );
11fdf7f2 366 *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3, arg4, arg5 ) );
7c673cae
FG
367 }
368
369 template<
370 class Processor, typename Arg1, typename Arg2,
371 typename Arg3, typename Arg4, typename Arg5, typename Arg6 >
372 void create_processor_impl6(
373 const processor_holder_ptr_type & pProcessor,
374 const processor_context & context,
375 Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6 )
376 {
377 processorSet_.insert( pProcessor );
11fdf7f2 378 *pProcessor = processor_holder_type( new Processor( context, arg1, arg2, arg3, arg4, arg5, arg6 ) );
7c673cae
FG
379 }
380
381 void destroy_processor_impl( const processor_handle & processor )
382 {
383 const processor_holder_ptr_type pProcessor = processor.lock();
384
385 if ( pProcessor != 0 )
386 {
387 processorSet_.erase( pProcessor );
388 }
389 }
390
391 void initiate_processor_impl( const processor_handle & processor )
392 {
393 const processor_holder_ptr_type pProcessor = processor.lock();
394
395 if ( pProcessor != 0 )
396 {
397 ( *pProcessor )->initiate();
398 }
399 }
400
401 void terminate_processor_impl( const processor_handle & processor )
402 {
403 const processor_holder_ptr_type pProcessor = processor.lock();
404
405 if ( pProcessor != 0 )
406 {
407 ( *pProcessor )->terminate();
408 }
409 }
410
411 void queue_event_impl(
412 const processor_handle & processor, const event_ptr_type & pEvent )
413 {
414 const processor_holder_ptr_type pProcessor = processor.lock();
415
416 if ( pProcessor != 0 )
417 {
418 ( *pProcessor )->process_event( *pEvent );
419 }
420 }
421
422 typedef std::set<
423 processor_holder_ptr_type,
424 std::less< processor_holder_ptr_type >,
425 typename boost::detail::allocator::rebind_to<
426 Allocator, processor_holder_ptr_type >::type
427 > event_processor_set_type;
428
429 event_processor_set_type processorSet_;
430};
431
432
433} // namespace statechart
434} // namespace boost
435
436
437
438#endif