Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ASIO_DETAIL_HANDLER_QUEUE_HPP
00012 #define ASIO_DETAIL_HANDLER_QUEUE_HPP
00013
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017
00018 #include "asio/detail/push_options.hpp"
00019
00020 #include "asio/detail/handler_alloc_helpers.hpp"
00021 #include "asio/detail/handler_invoke_helpers.hpp"
00022 #include "asio/detail/noncopyable.hpp"
00023
00024 namespace asio {
00025 namespace detail {
00026
00027 class handler_queue
00028 : private noncopyable
00029 {
00030 public:
00031
00032 class handler
00033 : private noncopyable
00034 {
00035 public:
00036 void invoke()
00037 {
00038 invoke_func_(this);
00039 }
00040
00041 void destroy()
00042 {
00043 destroy_func_(this);
00044 }
00045
00046 protected:
00047 typedef void (*invoke_func_type)(handler*);
00048 typedef void (*destroy_func_type)(handler*);
00049
00050 handler(invoke_func_type invoke_func,
00051 destroy_func_type destroy_func)
00052 : next_(0),
00053 invoke_func_(invoke_func),
00054 destroy_func_(destroy_func)
00055 {
00056 }
00057
00058 ~handler()
00059 {
00060 }
00061
00062 private:
00063 friend class handler_queue;
00064 handler* next_;
00065 invoke_func_type invoke_func_;
00066 destroy_func_type destroy_func_;
00067 };
00068
00069
00070 class scoped_ptr
00071 : private noncopyable
00072 {
00073 public:
00074 explicit scoped_ptr(handler* h)
00075 : handler_(h)
00076 {
00077 }
00078
00079 ~scoped_ptr()
00080 {
00081 if (handler_)
00082 handler_->destroy();
00083 }
00084
00085 handler* get() const
00086 {
00087 return handler_;
00088 }
00089
00090 handler* release()
00091 {
00092 handler* tmp = handler_;
00093 handler_ = 0;
00094 return tmp;
00095 }
00096
00097 private:
00098 handler* handler_;
00099 };
00100
00101
00102 handler_queue()
00103 : front_(0),
00104 back_(0)
00105 {
00106 }
00107
00108
00109 template <typename Handler>
00110 static handler* wrap(Handler h)
00111 {
00112
00113 typedef handler_wrapper<Handler> value_type;
00114 typedef handler_alloc_traits<Handler, value_type> alloc_traits;
00115 raw_handler_ptr<alloc_traits> raw_ptr(h);
00116 handler_ptr<alloc_traits> ptr(raw_ptr, h);
00117 return ptr.release();
00118 }
00119
00120
00121 handler* front()
00122 {
00123 return front_;
00124 }
00125
00126
00127 void pop()
00128 {
00129 if (front_)
00130 {
00131 handler* tmp = front_;
00132 front_ = front_->next_;
00133 if (front_ == 0)
00134 back_ = 0;
00135 tmp->next_= 0;
00136 }
00137 }
00138
00139
00140 void push(handler* h)
00141 {
00142 h->next_ = 0;
00143 if (back_)
00144 {
00145 back_->next_ = h;
00146 back_ = h;
00147 }
00148 else
00149 {
00150 front_ = back_ = h;
00151 }
00152 }
00153
00154
00155 bool empty() const
00156 {
00157 return front_ == 0;
00158 }
00159
00160 private:
00161
00162 template <typename Handler>
00163 class handler_wrapper
00164 : public handler
00165 {
00166 public:
00167 handler_wrapper(Handler h)
00168 : handler(
00169 &handler_wrapper<Handler>::do_call,
00170 &handler_wrapper<Handler>::do_destroy),
00171 handler_(h)
00172 {
00173 }
00174
00175 static void do_call(handler* base)
00176 {
00177
00178 typedef handler_wrapper<Handler> this_type;
00179 this_type* h(static_cast<this_type*>(base));
00180 typedef handler_alloc_traits<Handler, this_type> alloc_traits;
00181 handler_ptr<alloc_traits> ptr(h->handler_, h);
00182
00183
00184
00185 Handler handler(h->handler_);
00186
00187
00188 ptr.reset();
00189
00190
00191 asio_handler_invoke_helpers::invoke(handler, &handler);
00192 }
00193
00194 static void do_destroy(handler* base)
00195 {
00196
00197 typedef handler_wrapper<Handler> this_type;
00198 this_type* h(static_cast<this_type*>(base));
00199 typedef handler_alloc_traits<Handler, this_type> alloc_traits;
00200 handler_ptr<alloc_traits> ptr(h->handler_, h);
00201
00202
00203
00204
00205
00206 Handler handler(h->handler_);
00207 (void)handler;
00208
00209
00210 ptr.reset();
00211 }
00212
00213 private:
00214 Handler handler_;
00215 };
00216
00217
00218 handler* front_;
00219
00220
00221 handler* back_;
00222 };
00223
00224 }
00225 }
00226
00227 #include "asio/detail/pop_options.hpp"
00228
00229 #endif // ASIO_DETAIL_HANDLER_QUEUE_HPP