5 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP
12 #define BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/push_options.hpp>
20 #include <boost/asio/detail/handler_alloc_helpers.hpp>
21 #include <boost/asio/detail/handler_invoke_helpers.hpp>
22 #include <boost/asio/detail/noncopyable.hpp>
32 // Base class for handlers in the queue.
48 typedef void (*invoke_func_type
)(handler
*);
49 typedef void (*destroy_func_type
)(handler
*);
51 handler(invoke_func_type invoke_func
,
52 destroy_func_type destroy_func
)
54 invoke_func_(invoke_func
),
55 destroy_func_(destroy_func
)
64 friend class handler_queue
;
66 invoke_func_type invoke_func_
;
67 destroy_func_type destroy_func_
;
70 // Smart point to manager handler lifetimes.
75 explicit scoped_ptr(handler
* h
)
93 handler
* tmp
= handler_
;
109 // Wrap a handler to be pushed into the queue.
110 template <typename Handler
>
111 static handler
* wrap(Handler h
)
113 // Allocate and construct an object to wrap the handler.
114 typedef handler_wrapper
<Handler
> value_type
;
115 typedef handler_alloc_traits
<Handler
, value_type
> alloc_traits
;
116 raw_handler_ptr
<alloc_traits
> raw_ptr(h
);
117 handler_ptr
<alloc_traits
> ptr(raw_ptr
, h
);
118 return ptr
.release();
121 // Get the handler at the front of the queue.
127 // Pop a handler from the front of the queue.
132 handler
* tmp
= front_
;
133 front_
= front_
->next_
;
140 // Push a handler on to the back of the queue.
141 void push(handler
* h
)
155 // Whether the queue is empty.
162 // Template wrapper for handlers.
163 template <typename Handler
>
164 class handler_wrapper
168 handler_wrapper(Handler h
)
170 &handler_wrapper
<Handler
>::do_call
,
171 &handler_wrapper
<Handler
>::do_destroy
),
176 static void do_call(handler
* base
)
178 // Take ownership of the handler object.
179 typedef handler_wrapper
<Handler
> this_type
;
180 this_type
* h(static_cast<this_type
*>(base
));
181 typedef handler_alloc_traits
<Handler
, this_type
> alloc_traits
;
182 handler_ptr
<alloc_traits
> ptr(h
->handler_
, h
);
184 // Make a copy of the handler so that the memory can be deallocated before
185 // the upcall is made.
186 Handler
handler(h
->handler_
);
188 // Free the memory associated with the handler.
192 boost_asio_handler_invoke_helpers::invoke(handler
, &handler
);
195 static void do_destroy(handler
* base
)
197 // Take ownership of the handler object.
198 typedef handler_wrapper
<Handler
> this_type
;
199 this_type
* h(static_cast<this_type
*>(base
));
200 typedef handler_alloc_traits
<Handler
, this_type
> alloc_traits
;
201 handler_ptr
<alloc_traits
> ptr(h
->handler_
, h
);
203 // A sub-object of the handler may be the true owner of the memory
204 // associated with the handler. Consequently, a local copy of the handler
205 // is required to ensure that any owning sub-object remains valid until
206 // after we have deallocated the memory here.
207 Handler
handler(h
->handler_
);
210 // Free the memory associated with the handler.
218 // The front of the queue.
221 // The back of the queue.
225 } // namespace detail
229 #include <boost/asio/detail/pop_options.hpp>
231 #endif // BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP