]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp03/services/stream_socket_service.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / services / stream_socket_service.hpp
1 //
2 // stream_socket_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2016 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 //
10
11 #ifndef SERVICES_STREAM_SOCKET_SERVICE_HPP
12 #define SERVICES_STREAM_SOCKET_SERVICE_HPP
13
14 #include <boost/asio.hpp>
15 #include <boost/noncopyable.hpp>
16 #include <boost/lexical_cast.hpp>
17 #include "logger.hpp"
18
19 namespace services {
20
21 /// Debugging stream socket service that wraps the normal stream socket service.
22 template <typename Protocol>
23 class stream_socket_service
24 : public boost::asio::io_service::service
25 {
26 private:
27 /// The type of the wrapped stream socket service.
28 typedef boost::asio::stream_socket_service<Protocol> service_impl_type;
29
30 public:
31 /// The unique service identifier.
32 static boost::asio::io_service::id id;
33
34 /// The protocol type.
35 typedef Protocol protocol_type;
36
37 /// The endpoint type.
38 typedef typename Protocol::endpoint endpoint_type;
39
40 /// The implementation type of a stream socket.
41 typedef typename service_impl_type::implementation_type implementation_type;
42
43 /// The native type of a stream socket.
44 typedef typename service_impl_type::native_handle_type native_handle_type;
45
46 /// Construct a new stream socket service for the specified io_service.
47 explicit stream_socket_service(boost::asio::io_service& io_service)
48 : boost::asio::io_service::service(io_service),
49 service_impl_(boost::asio::use_service<service_impl_type>(io_service)),
50 logger_(io_service, "stream_socket")
51 {
52 }
53
54 /// Destroy all user-defined handler objects owned by the service.
55 void shutdown_service()
56 {
57 }
58
59 /// Construct a new stream socket implementation.
60 void construct(implementation_type& impl)
61 {
62 service_impl_.construct(impl);
63 }
64
65 /// Destroy a stream socket implementation.
66 void destroy(implementation_type& impl)
67 {
68 service_impl_.destroy(impl);
69 }
70
71 /// Open a new stream socket implementation.
72 boost::system::error_code open(implementation_type& impl,
73 const protocol_type& protocol, boost::system::error_code& ec)
74 {
75 logger_.log("Opening new socket");
76 return service_impl_.open(impl, protocol, ec);
77 }
78
79 /// Open a stream socket from an existing native socket.
80 boost::system::error_code assign(implementation_type& impl,
81 const protocol_type& protocol, const native_handle_type& native_socket,
82 boost::system::error_code& ec)
83 {
84 logger_.log("Assigning from a native socket");
85 return service_impl_.assign(impl, protocol, native_socket, ec);
86 }
87
88 /// Determine whether the socket is open.
89 bool is_open(const implementation_type& impl) const
90 {
91 logger_.log("Checking if socket is open");
92 return service_impl_.is_open(impl);
93 }
94
95 /// Close a stream socket implementation.
96 boost::system::error_code close(implementation_type& impl,
97 boost::system::error_code& ec)
98 {
99 logger_.log("Closing socket");
100 return service_impl_.close(impl, ec);
101 }
102
103 /// Determine whether the socket is at the out-of-band data mark.
104 bool at_mark(const implementation_type& impl,
105 boost::system::error_code& ec) const
106 {
107 logger_.log("Checking if socket is at out-of-band data mark");
108 return service_impl_.at_mark(impl, ec);
109 }
110
111 /// Determine the number of bytes available for reading.
112 std::size_t available(const implementation_type& impl,
113 boost::system::error_code& ec) const
114 {
115 logger_.log("Determining number of bytes available for reading");
116 return service_impl_.available(impl, ec);
117 }
118
119 /// Bind the stream socket to the specified local endpoint.
120 boost::system::error_code bind(implementation_type& impl,
121 const endpoint_type& endpoint, boost::system::error_code& ec)
122 {
123 logger_.log("Binding socket");
124 return service_impl_.bind(impl, endpoint, ec);
125 }
126
127 /// Connect the stream socket to the specified endpoint.
128 boost::system::error_code connect(implementation_type& impl,
129 const endpoint_type& peer_endpoint, boost::system::error_code& ec)
130 {
131 logger_.log("Connecting socket to " +
132 boost::lexical_cast<std::string>(peer_endpoint));
133 return service_impl_.connect(impl, peer_endpoint, ec);
134 }
135
136 /// Handler to wrap asynchronous connect completion.
137 template <typename Handler>
138 class connect_handler
139 {
140 public:
141 connect_handler(Handler h, logger& l)
142 : handler_(h),
143 logger_(l)
144 {
145 }
146
147 void operator()(const boost::system::error_code& e)
148 {
149 if (e)
150 {
151 std::string msg = "Asynchronous connect failed: ";
152 msg += e.message();
153 logger_.log(msg);
154 }
155 else
156 {
157 logger_.log("Asynchronous connect succeeded");
158 }
159
160 handler_(e);
161 }
162
163 private:
164 Handler handler_;
165 logger& logger_;
166 };
167
168 /// Start an asynchronous connect.
169 template <typename Handler>
170 void async_connect(implementation_type& impl,
171 const endpoint_type& peer_endpoint, Handler handler)
172 {
173 logger_.log("Starting asynchronous connect to " +
174 boost::lexical_cast<std::string>(peer_endpoint));
175 service_impl_.async_connect(impl, peer_endpoint,
176 connect_handler<Handler>(handler, logger_));
177 }
178
179 /// Set a socket option.
180 template <typename Option>
181 boost::system::error_code set_option(implementation_type& impl,
182 const Option& option, boost::system::error_code& ec)
183 {
184 logger_.log("Setting socket option");
185 return service_impl_.set_option(impl, option, ec);
186 }
187
188 /// Get a socket option.
189 template <typename Option>
190 boost::system::error_code get_option(const implementation_type& impl,
191 Option& option, boost::system::error_code& ec) const
192 {
193 logger_.log("Getting socket option");
194 return service_impl_.get_option(impl, option, ec);
195 }
196
197 /// Perform an IO control command on the socket.
198 template <typename IO_Control_Command>
199 boost::system::error_code io_control(implementation_type& impl,
200 IO_Control_Command& command, boost::system::error_code& ec)
201 {
202 logger_.log("Performing IO control command on socket");
203 return service_impl_.io_control(impl, command, ec);
204 }
205
206 /// Get the local endpoint.
207 endpoint_type local_endpoint(const implementation_type& impl,
208 boost::system::error_code& ec) const
209 {
210 logger_.log("Getting socket's local endpoint");
211 return service_impl_.local_endpoint(impl, ec);
212 }
213
214 /// Get the remote endpoint.
215 endpoint_type remote_endpoint(const implementation_type& impl,
216 boost::system::error_code& ec) const
217 {
218 logger_.log("Getting socket's remote endpoint");
219 return service_impl_.remote_endpoint(impl, ec);
220 }
221
222 /// Disable sends or receives on the socket.
223 boost::system::error_code shutdown(implementation_type& impl,
224 boost::asio::socket_base::shutdown_type what,
225 boost::system::error_code& ec)
226 {
227 logger_.log("Shutting down socket");
228 return service_impl_.shutdown(impl, what, ec);
229 }
230
231 /// Send the given data to the peer.
232 template <typename Const_Buffers>
233 std::size_t send(implementation_type& impl, const Const_Buffers& buffers,
234 boost::asio::socket_base::message_flags flags,
235 boost::system::error_code& ec)
236 {
237 logger_.log("Sending data on socket");
238 return service_impl_.send(impl, buffers, flags, ec);
239 }
240
241 /// Handler to wrap asynchronous send completion.
242 template <typename Handler>
243 class send_handler
244 {
245 public:
246 send_handler(Handler h, logger& l)
247 : handler_(h),
248 logger_(l)
249 {
250 }
251
252 void operator()(const boost::system::error_code& e,
253 std::size_t bytes_transferred)
254 {
255 if (e)
256 {
257 std::string msg = "Asynchronous send failed: ";
258 msg += e.message();
259 logger_.log(msg);
260 }
261 else
262 {
263 logger_.log("Asynchronous send succeeded");
264 }
265
266 handler_(e, bytes_transferred);
267 }
268
269 private:
270 Handler handler_;
271 logger& logger_;
272 };
273
274 /// Start an asynchronous send.
275 template <typename Const_Buffers, typename Handler>
276 void async_send(implementation_type& impl, const Const_Buffers& buffers,
277 boost::asio::socket_base::message_flags flags, Handler handler)
278 {
279 logger_.log("Starting asynchronous send");
280 service_impl_.async_send(impl, buffers, flags,
281 send_handler<Handler>(handler, logger_));
282 }
283
284 /// Receive some data from the peer.
285 template <typename Mutable_Buffers>
286 std::size_t receive(implementation_type& impl,
287 const Mutable_Buffers& buffers,
288 boost::asio::socket_base::message_flags flags,
289 boost::system::error_code& ec)
290 {
291 logger_.log("Receiving data on socket");
292 return service_impl_.receive(impl, buffers, flags, ec);
293 }
294
295 /// Handler to wrap asynchronous receive completion.
296 template <typename Handler>
297 class receive_handler
298 {
299 public:
300 receive_handler(Handler h, logger& l)
301 : handler_(h),
302 logger_(l)
303 {
304 }
305
306 void operator()(const boost::system::error_code& e,
307 std::size_t bytes_transferred)
308 {
309 if (e)
310 {
311 std::string msg = "Asynchronous receive failed: ";
312 msg += e.message();
313 logger_.log(msg);
314 }
315 else
316 {
317 logger_.log("Asynchronous receive succeeded");
318 }
319
320 handler_(e, bytes_transferred);
321 }
322
323 private:
324 Handler handler_;
325 logger& logger_;
326 };
327
328 /// Start an asynchronous receive.
329 template <typename Mutable_Buffers, typename Handler>
330 void async_receive(implementation_type& impl, const Mutable_Buffers& buffers,
331 boost::asio::socket_base::message_flags flags, Handler handler)
332 {
333 logger_.log("Starting asynchronous receive");
334 service_impl_.async_receive(impl, buffers, flags,
335 receive_handler<Handler>(handler, logger_));
336 }
337
338 private:
339 /// The wrapped stream socket service.
340 service_impl_type& service_impl_;
341
342 /// The logger used for writing debug messages.
343 mutable logger logger_;
344 };
345
346 template <typename Protocol>
347 boost::asio::io_service::id stream_socket_service<Protocol>::id;
348
349 } // namespace services
350
351 #endif // SERVICES_STREAM_SOCKET_SERVICE_HPP