Realistic 3D camera system
3D camera system components
reactive_socket_service_base.hpp
Go to the documentation of this file.
1 //
2 // detail/reactive_socket_service_base.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 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 ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP
12 #define ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 
20 #if !defined(ASIO_HAS_IOCP) \
21  && !defined(ASIO_WINDOWS_RUNTIME)
22 
23 #include "asio/buffer.hpp"
24 #include "asio/error.hpp"
25 #include "asio/io_service.hpp"
26 #include "asio/socket_base.hpp"
33 #include "asio/detail/reactor.hpp"
38 
40 
41 namespace asio {
42 namespace detail {
43 
45 {
46 public:
47  // The native type of a socket.
49 
50  // The implementation type of the socket.
52  {
53  // The native socket representation.
55 
56  // The current state of the socket.
58 
59  // Per-descriptor data used by the reactor.
60  reactor::per_descriptor_data reactor_data_;
61  };
62 
63  // Constructor.
66 
67  // Destroy all user-defined handler objects owned by the service.
69 
70  // Construct a new socket implementation.
72 
73  // Move-construct a new socket implementation.
75  base_implementation_type& other_impl);
76 
77  // Move-assign from another socket implementation.
79  reactive_socket_service_base& other_service,
80  base_implementation_type& other_impl);
81 
82  // Destroy a socket implementation.
84 
85  // Determine whether the socket is open.
86  bool is_open(const base_implementation_type& impl) const
87  {
88  return impl.socket_ != invalid_socket;
89  }
90 
91  // Destroy a socket implementation.
94 
95  // Get the native socket representation.
96  native_handle_type native_handle(base_implementation_type& impl)
97  {
98  return impl.socket_;
99  }
100 
101  // Cancel all operations associated with the socket.
104 
105  // Determine whether the socket is at the out-of-band data mark.
107  asio::error_code& ec) const
108  {
109  return socket_ops::sockatmark(impl.socket_, ec);
110  }
111 
112  // Determine the number of bytes available for reading.
113  std::size_t available(const base_implementation_type& impl,
114  asio::error_code& ec) const
115  {
116  return socket_ops::available(impl.socket_, ec);
117  }
118 
119  // Place the socket into the state where it will listen for new connections.
121  int backlog, asio::error_code& ec)
122  {
123  socket_ops::listen(impl.socket_, backlog, ec);
124  return ec;
125  }
126 
127  // Perform an IO control command on the socket.
128  template <typename IO_Control_Command>
130  IO_Control_Command& command, asio::error_code& ec)
131  {
132  socket_ops::ioctl(impl.socket_, impl.state_, command.name(),
133  static_cast<ioctl_arg_type*>(command.data()), ec);
134  return ec;
135  }
136 
137  // Gets the non-blocking mode of the socket.
138  bool non_blocking(const base_implementation_type& impl) const
139  {
140  return (impl.state_ & socket_ops::user_set_non_blocking) != 0;
141  }
142 
143  // Sets the non-blocking mode of the socket.
145  bool mode, asio::error_code& ec)
146  {
147  socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec);
148  return ec;
149  }
150 
151  // Gets the non-blocking mode of the native socket implementation.
153  {
154  return (impl.state_ & socket_ops::internal_non_blocking) != 0;
155  }
156 
157  // Sets the non-blocking mode of the native socket implementation.
159  bool mode, asio::error_code& ec)
160  {
162  return ec;
163  }
164 
165  // Disable sends or receives on the socket.
168  {
169  socket_ops::shutdown(impl.socket_, what, ec);
170  return ec;
171  }
172 
173  // Send the given data to the peer.
174  template <typename ConstBufferSequence>
176  const ConstBufferSequence& buffers,
178  {
180  ConstBufferSequence> bufs(buffers);
181 
182  return socket_ops::sync_send(impl.socket_, impl.state_,
183  bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
184  }
185 
186  // Wait until data can be sent without blocking.
189  {
190  // Wait for socket to become ready.
191  socket_ops::poll_write(impl.socket_, impl.state_, ec);
192 
193  return 0;
194  }
195 
196  // Start an asynchronous send. The data being sent must be valid for the
197  // lifetime of the asynchronous operation.
198  template <typename ConstBufferSequence, typename Handler>
200  const ConstBufferSequence& buffers,
201  socket_base::message_flags flags, Handler& handler)
202  {
203  bool is_continuation =
205 
206  // Allocate and construct an operation to wrap the handler.
208  typename op::ptr p = { asio::detail::addressof(handler),
210  sizeof(op), handler), 0 };
211  p.p = new (p.v) op(impl.socket_, buffers, flags, handler);
212 
213  ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send"));
214 
215  start_op(impl, reactor::write_op, p.p, is_continuation, true,
218  ConstBufferSequence>::all_empty(buffers)));
219  p.v = p.p = 0;
220  }
221 
222  // Start an asynchronous wait until data can be sent without blocking.
223  template <typename Handler>
225  socket_base::message_flags, Handler& handler)
226  {
227  bool is_continuation =
229 
230  // Allocate and construct an operation to wrap the handler.
232  typename op::ptr p = { asio::detail::addressof(handler),
234  sizeof(op), handler), 0 };
235  p.p = new (p.v) op(handler);
236 
237  ASIO_HANDLER_CREATION((p.p, "socket",
238  &impl, "async_send(null_buffers)"));
239 
240  start_op(impl, reactor::write_op, p.p, is_continuation, false, false);
241  p.v = p.p = 0;
242  }
243 
244  // Receive some data from the peer. Returns the number of bytes received.
245  template <typename MutableBufferSequence>
247  const MutableBufferSequence& buffers,
249  {
251  MutableBufferSequence> bufs(buffers);
252 
253  return socket_ops::sync_recv(impl.socket_, impl.state_,
254  bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
255  }
256 
257  // Wait until data can be received without blocking.
260  {
261  // Wait for socket to become ready.
262  socket_ops::poll_read(impl.socket_, impl.state_, ec);
263 
264  return 0;
265  }
266 
267  // Start an asynchronous receive. The buffer for the data being received
268  // must be valid for the lifetime of the asynchronous operation.
269  template <typename MutableBufferSequence, typename Handler>
271  const MutableBufferSequence& buffers,
272  socket_base::message_flags flags, Handler& handler)
273  {
274  bool is_continuation =
276 
277  // Allocate and construct an operation to wrap the handler.
279  typename op::ptr p = { asio::detail::addressof(handler),
281  sizeof(op), handler), 0 };
282  p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler);
283 
284  ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive"));
285 
286  start_op(impl,
287  (flags & socket_base::message_out_of_band)
288  ? reactor::except_op : reactor::read_op,
289  p.p, is_continuation,
290  (flags & socket_base::message_out_of_band) == 0,
293  MutableBufferSequence>::all_empty(buffers)));
294  p.v = p.p = 0;
295  }
296 
297  // Wait until data can be received without blocking.
298  template <typename Handler>
300  socket_base::message_flags flags, Handler& handler)
301  {
302  bool is_continuation =
304 
305  // Allocate and construct an operation to wrap the handler.
307  typename op::ptr p = { asio::detail::addressof(handler),
309  sizeof(op), handler), 0 };
310  p.p = new (p.v) op(handler);
311 
312  ASIO_HANDLER_CREATION((p.p, "socket",
313  &impl, "async_receive(null_buffers)"));
314 
315  start_op(impl,
316  (flags & socket_base::message_out_of_band)
317  ? reactor::except_op : reactor::read_op,
318  p.p, is_continuation, false, false);
319  p.v = p.p = 0;
320  }
321 
322  // Receive some data with associated flags. Returns the number of bytes
323  // received.
324  template <typename MutableBufferSequence>
326  const MutableBufferSequence& buffers,
329  {
331  MutableBufferSequence> bufs(buffers);
332 
333  return socket_ops::sync_recvmsg(impl.socket_, impl.state_,
334  bufs.buffers(), bufs.count(), in_flags, out_flags, ec);
335  }
336 
337  // Wait until data can be received without blocking.
341  {
342  // Wait for socket to become ready.
343  socket_ops::poll_read(impl.socket_, impl.state_, ec);
344 
345  // Clear out_flags, since we cannot give it any other sensible value when
346  // performing a null_buffers operation.
347  out_flags = 0;
348 
349  return 0;
350  }
351 
352  // Start an asynchronous receive. The buffer for the data being received
353  // must be valid for the lifetime of the asynchronous operation.
354  template <typename MutableBufferSequence, typename Handler>
356  const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
357  socket_base::message_flags& out_flags, Handler& handler)
358  {
359  bool is_continuation =
361 
362  // Allocate and construct an operation to wrap the handler.
364  typename op::ptr p = { asio::detail::addressof(handler),
366  sizeof(op), handler), 0 };
367  p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler);
368 
369  ASIO_HANDLER_CREATION((p.p, "socket",
370  &impl, "async_receive_with_flags"));
371 
372  start_op(impl,
373  (in_flags & socket_base::message_out_of_band)
374  ? reactor::except_op : reactor::read_op,
375  p.p, is_continuation,
376  (in_flags & socket_base::message_out_of_band) == 0, false);
377  p.v = p.p = 0;
378  }
379 
380  // Wait until data can be received without blocking.
381  template <typename Handler>
383  const null_buffers&, socket_base::message_flags in_flags,
384  socket_base::message_flags& out_flags, Handler& handler)
385  {
386  bool is_continuation =
388 
389  // Allocate and construct an operation to wrap the handler.
391  typename op::ptr p = { asio::detail::addressof(handler),
393  sizeof(op), handler), 0 };
394  p.p = new (p.v) op(handler);
395 
396  ASIO_HANDLER_CREATION((p.p, "socket", &impl,
397  "async_receive_with_flags(null_buffers)"));
398 
399  // Clear out_flags, since we cannot give it any other sensible value when
400  // performing a null_buffers operation.
401  out_flags = 0;
402 
403  start_op(impl,
404  (in_flags & socket_base::message_out_of_band)
405  ? reactor::except_op : reactor::read_op,
406  p.p, is_continuation, false, false);
407  p.v = p.p = 0;
408  }
409 
410 protected:
411  // Open a new socket implementation.
413  base_implementation_type& impl, int af,
414  int type, int protocol, asio::error_code& ec);
415 
416  // Assign a native socket to a socket implementation.
418  base_implementation_type& impl, int type,
419  const native_handle_type& native_socket, asio::error_code& ec);
420 
421  // Start the asynchronous read or write operation.
422  ASIO_DECL void start_op(base_implementation_type& impl, int op_type,
423  reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop);
424 
425  // Start the asynchronous accept operation.
427  reactor_op* op, bool is_continuation, bool peer_is_open);
428 
429  // Start the asynchronous connect operation.
431  reactor_op* op, bool is_continuation,
432  const socket_addr_type* addr, size_t addrlen);
433 
434  // The selector that performs event demultiplexing for the service.
436 };
437 
438 } // namespace detail
439 } // namespace asio
440 
442 
443 #if defined(ASIO_HEADER_ONLY)
445 #endif // defined(ASIO_HEADER_ONLY)
446 
447 #endif // !defined(ASIO_HAS_IOCP)
448  // && !defined(ASIO_WINDOWS_RUNTIME)
449 
450 #endif // ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP
int message_flags
Bitmask type for flags that can be passed to send and receive operations.
Definition: socket_base.hpp:53
bool set_user_non_blocking(socket_type s, state_type &state, bool value, asio::error_code &ec)
Definition: socket_ops.ipp:360
ASIO_DECL void start_op(base_implementation_type &impl, int op_type, reactor_op *op, bool is_continuation, bool is_non_blocking, bool noop)
bool at_mark(const base_implementation_type &impl, asio::error_code &ec) const
size_t send(base_implementation_type &impl, const null_buffers &, socket_base::message_flags, asio::error_code &ec)
Provides core I/O functionality.
Definition: io_service.hpp:184
size_t sync_recv(socket_type s, state_type state, buf *bufs, size_t count, int flags, bool all_empty, asio::error_code &ec)
Definition: socket_ops.ipp:790
Holds a buffer that cannot be modified.
Definition: buffer.hpp:211
bool sockatmark(socket_type s, asio::error_code &ec)
Definition: socket_ops.ipp:630
size_t sync_send(socket_type s, state_type state, const buf *bufs, size_t count, int flags, bool all_empty, asio::error_code &ec)
ASIO_DECL void destroy(base_implementation_type &impl)
size_t receive(base_implementation_type &impl, const null_buffers &, socket_base::message_flags, asio::error_code &ec)
asio::error_code listen(base_implementation_type &impl, int backlog, asio::error_code &ec)
ASIO_DECL reactive_socket_service_base(asio::io_service &io_service)
int poll_read(socket_type s, state_type state, asio::error_code &ec)
size_t receive(base_implementation_type &impl, const MutableBufferSequence &buffers, socket_base::message_flags flags, asio::error_code &ec)
int listen(socket_type s, int backlog, asio::error_code &ec)
Definition: socket_ops.ipp:684
sockaddr socket_addr_type
size_t send(base_implementation_type &impl, const ConstBufferSequence &buffers, socket_base::message_flags flags, asio::error_code &ec)
void async_receive_with_flags(base_implementation_type &impl, const null_buffers &, socket_base::message_flags in_flags, socket_base::message_flags &out_flags, Handler &handler)
ASIO_DECL asio::error_code do_assign(base_implementation_type &impl, int type, const native_handle_type &native_socket, asio::error_code &ec)
asio::error_code io_control(base_implementation_type &impl, IO_Control_Command &command, asio::error_code &ec)
ASIO_DECL void start_connect_op(base_implementation_type &impl, reactor_op *op, bool is_continuation, const socket_addr_type *addr, size_t addrlen)
void async_receive_with_flags(base_implementation_type &impl, const MutableBufferSequence &buffers, socket_base::message_flags in_flags, socket_base::message_flags &out_flags, Handler &handler)
const MutableBufferSequence & buffers
Definition: read.hpp:521
ASIO_DECL void base_move_construct(base_implementation_type &impl, base_implementation_type &other_impl)
int ioctl(socket_type s, state_type &state, int cmd, ioctl_arg_type *arg, asio::error_code &ec)
ASIO_DECL void construct(base_implementation_type &impl)
ASIO_DECL asio::error_code do_open(base_implementation_type &impl, int af, int type, int protocol, asio::error_code &ec)
size_t receive_with_flags(base_implementation_type &impl, const MutableBufferSequence &buffers, socket_base::message_flags in_flags, socket_base::message_flags &out_flags, asio::error_code &ec)
native_handle_type native_handle(base_implementation_type &impl)
Holds a buffer that can be modified.
Definition: buffer.hpp:91
class select_reactor reactor
Definition: reactor_fwd.hpp:34
int poll_write(socket_type s, state_type state, asio::error_code &ec)
unsigned char state_type
Definition: socket_ops.hpp:59
shutdown_type
Different ways a socket may be shutdown.
Definition: socket_base.hpp:34
size_t available(socket_type s, asio::error_code &ec)
Definition: socket_ops.ipp:660
bool is_continuation(Context &context)
bool is_open(const base_implementation_type &impl) const
size_t receive_with_flags(base_implementation_type &impl, const null_buffers &, socket_base::message_flags, socket_base::message_flags &out_flags, asio::error_code &ec)
Class to represent an error code value.
Definition: error_code.hpp:80
size_t sync_recvmsg(socket_type s, state_type state, buf *bufs, size_t count, int in_flags, int &out_flags, asio::error_code &ec)
#define ASIO_DECL
Definition: config.hpp:43
ASIO_DECL void base_move_assign(base_implementation_type &impl, reactive_socket_service_base &other_service, base_implementation_type &other_impl)
void async_receive(base_implementation_type &impl, const null_buffers &, socket_base::message_flags flags, Handler &handler)
void async_send(base_implementation_type &impl, const ConstBufferSequence &buffers, socket_base::message_flags flags, Handler &handler)
ASIO_DECL void start_accept_op(base_implementation_type &impl, reactor_op *op, bool is_continuation, bool peer_is_open)
ASIO_DECL asio::error_code close(base_implementation_type &impl, asio::error_code &ec)
bool native_non_blocking(const base_implementation_type &impl) const
asio::error_code non_blocking(base_implementation_type &impl, bool mode, asio::error_code &ec)
void async_receive(base_implementation_type &impl, const MutableBufferSequence &buffers, socket_base::message_flags flags, Handler &handler)
void * allocate(std::size_t s, Handler &h)
int shutdown(socket_type s, int what, asio::error_code &ec)
Definition: socket_ops.ipp:452
ASIO_DECL asio::error_code cancel(base_implementation_type &impl, asio::error_code &ec)
const int invalid_socket
bool non_blocking(const base_implementation_type &impl) const
asio::error_code native_non_blocking(base_implementation_type &impl, bool mode, asio::error_code &ec)
#define ASIO_HANDLER_CREATION(args)
bool set_internal_non_blocking(socket_type s, state_type &state, bool value, asio::error_code &ec)
Definition: socket_ops.ipp:404
std::size_t available(const base_implementation_type &impl, asio::error_code &ec) const
asio::error_code shutdown(base_implementation_type &impl, socket_base::shutdown_type what, asio::error_code &ec)
void async_send(base_implementation_type &impl, const null_buffers &, socket_base::message_flags, Handler &handler)