fix doc example typo
[boost.git] / boost / asio / detail / handler_queue.hpp
blobccc1b0c0d7aac688c79e40cbd0bbdf1e22cc6e5f
1 //
2 // handler_queue.hpp
3 // ~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
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)
9 //
11 #ifndef BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP
12 #define BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
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>
24 namespace boost {
25 namespace asio {
26 namespace detail {
28 class handler_queue
29 : private noncopyable
31 public:
32 // Base class for handlers in the queue.
33 class handler
34 : private noncopyable
36 public:
37 void invoke()
39 invoke_func_(this);
42 void destroy()
44 destroy_func_(this);
47 protected:
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)
53 : next_(0),
54 invoke_func_(invoke_func),
55 destroy_func_(destroy_func)
59 ~handler()
63 private:
64 friend class handler_queue;
65 handler* next_;
66 invoke_func_type invoke_func_;
67 destroy_func_type destroy_func_;
70 // Smart point to manager handler lifetimes.
71 class scoped_ptr
72 : private noncopyable
74 public:
75 explicit scoped_ptr(handler* h)
76 : handler_(h)
80 ~scoped_ptr()
82 if (handler_)
83 handler_->destroy();
86 handler* get() const
88 return handler_;
91 handler* release()
93 handler* tmp = handler_;
94 handler_ = 0;
95 return tmp;
98 private:
99 handler* handler_;
102 // Constructor.
103 handler_queue()
104 : front_(0),
105 back_(0)
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.
122 handler* front()
124 return front_;
127 // Pop a handler from the front of the queue.
128 void pop()
130 if (front_)
132 handler* tmp = front_;
133 front_ = front_->next_;
134 if (front_ == 0)
135 back_ = 0;
136 tmp->next_= 0;
140 // Push a handler on to the back of the queue.
141 void push(handler* h)
143 h->next_ = 0;
144 if (back_)
146 back_->next_ = h;
147 back_ = h;
149 else
151 front_ = back_ = h;
155 // Whether the queue is empty.
156 bool empty() const
158 return front_ == 0;
161 private:
162 // Template wrapper for handlers.
163 template <typename Handler>
164 class handler_wrapper
165 : public handler
167 public:
168 handler_wrapper(Handler h)
169 : handler(
170 &handler_wrapper<Handler>::do_call,
171 &handler_wrapper<Handler>::do_destroy),
172 handler_(h)
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.
189 ptr.reset();
191 // Make the upcall.
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_);
208 (void)handler;
210 // Free the memory associated with the handler.
211 ptr.reset();
214 private:
215 Handler handler_;
218 // The front of the queue.
219 handler* front_;
221 // The back of the queue.
222 handler* back_;
225 } // namespace detail
226 } // namespace asio
227 } // namespace boost
229 #include <boost/asio/detail/pop_options.hpp>
231 #endif // BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP