Realistic 3D camera system
3D camera system components
win_iocp_handle_service.hpp
Go to the documentation of this file.
1 //
2 // detail/win_iocp_handle_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
7 //
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 //
11 
12 #ifndef ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP
13 #define ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP
14 
15 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 # pragma once
17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 
19 #include "asio/detail/config.hpp"
20 
21 #if defined(ASIO_HAS_IOCP)
22 
23 #include "asio/error.hpp"
24 #include "asio/io_service.hpp"
27 #include "asio/detail/cstdint.hpp"
29 #include "asio/detail/mutex.hpp"
34 
36 
37 namespace asio {
38 namespace detail {
39 
40 class win_iocp_handle_service
41 {
42 public:
43  // The native type of a stream handle.
44  typedef HANDLE native_handle_type;
45 
46  // The implementation type of the stream handle.
47  class implementation_type
48  {
49  public:
50  // Default constructor.
51  implementation_type()
52  : handle_(INVALID_HANDLE_VALUE),
53  safe_cancellation_thread_id_(0),
54  next_(0),
55  prev_(0)
56  {
57  }
58 
59  private:
60  // Only this service will have access to the internal values.
61  friend class win_iocp_handle_service;
62 
63  // The native stream handle representation.
64  native_handle_type handle_;
65 
66  // The ID of the thread from which it is safe to cancel asynchronous
67  // operations. 0 means no asynchronous operations have been started yet.
68  // ~0 means asynchronous operations have been started from more than one
69  // thread, and cancellation is not supported for the handle.
70  DWORD safe_cancellation_thread_id_;
71 
72  // Pointers to adjacent handle implementations in linked list.
73  implementation_type* next_;
74  implementation_type* prev_;
75  };
76 
77  ASIO_DECL win_iocp_handle_service(asio::io_service& io_service);
78 
79  // Destroy all user-defined handler objects owned by the service.
80  ASIO_DECL void shutdown_service();
81 
82  // Construct a new handle implementation.
83  ASIO_DECL void construct(implementation_type& impl);
84 
85  // Move-construct a new handle implementation.
86  ASIO_DECL void move_construct(implementation_type& impl,
87  implementation_type& other_impl);
88 
89  // Move-assign from another handle implementation.
90  ASIO_DECL void move_assign(implementation_type& impl,
91  win_iocp_handle_service& other_service,
92  implementation_type& other_impl);
93 
94  // Destroy a handle implementation.
95  ASIO_DECL void destroy(implementation_type& impl);
96 
97  // Assign a native handle to a handle implementation.
98  ASIO_DECL asio::error_code assign(implementation_type& impl,
99  const native_handle_type& handle, asio::error_code& ec);
100 
101  // Determine whether the handle is open.
102  bool is_open(const implementation_type& impl) const
103  {
104  return impl.handle_ != INVALID_HANDLE_VALUE;
105  }
106 
107  // Destroy a handle implementation.
108  ASIO_DECL asio::error_code close(implementation_type& impl,
109  asio::error_code& ec);
110 
111  // Get the native handle representation.
112  native_handle_type native_handle(const implementation_type& impl) const
113  {
114  return impl.handle_;
115  }
116 
117  // Cancel all operations associated with the handle.
118  ASIO_DECL asio::error_code cancel(implementation_type& impl,
119  asio::error_code& ec);
120 
121  // Write the given data. Returns the number of bytes written.
122  template <typename ConstBufferSequence>
123  size_t write_some(implementation_type& impl,
124  const ConstBufferSequence& buffers, asio::error_code& ec)
125  {
126  return write_some_at(impl, 0, buffers, ec);
127  }
128 
129  // Write the given data at the specified offset. Returns the number of bytes
130  // written.
131  template <typename ConstBufferSequence>
132  size_t write_some_at(implementation_type& impl, uint64_t offset,
133  const ConstBufferSequence& buffers, asio::error_code& ec)
134  {
136  buffer_sequence_adapter<asio::const_buffer,
137  ConstBufferSequence>::first(buffers);
138 
139  return do_write(impl, offset, buffer, ec);
140  }
141 
142  // Start an asynchronous write. The data being written must be valid for the
143  // lifetime of the asynchronous operation.
144  template <typename ConstBufferSequence, typename Handler>
145  void async_write_some(implementation_type& impl,
146  const ConstBufferSequence& buffers, Handler& handler)
147  {
148  // Allocate and construct an operation to wrap the handler.
149  typedef win_iocp_handle_write_op<ConstBufferSequence, Handler> op;
150  typename op::ptr p = { asio::detail::addressof(handler),
152  sizeof(op), handler), 0 };
153  p.p = new (p.v) op(buffers, handler);
154 
155  ASIO_HANDLER_CREATION((p.p, "handle", &impl, "async_write_some"));
156 
157  start_write_op(impl, 0,
158  buffer_sequence_adapter<asio::const_buffer,
159  ConstBufferSequence>::first(buffers), p.p);
160  p.v = p.p = 0;
161  }
162 
163  // Start an asynchronous write at a specified offset. The data being written
164  // must be valid for the lifetime of the asynchronous operation.
165  template <typename ConstBufferSequence, typename Handler>
166  void async_write_some_at(implementation_type& impl, uint64_t offset,
167  const ConstBufferSequence& buffers, Handler& handler)
168  {
169  // Allocate and construct an operation to wrap the handler.
170  typedef win_iocp_handle_write_op<ConstBufferSequence, Handler> op;
171  typename op::ptr p = { asio::detail::addressof(handler),
173  sizeof(op), handler), 0 };
174  p.p = new (p.v) op(buffers, handler);
175 
176  ASIO_HANDLER_CREATION((p.p, "handle", &impl, "async_write_some_at"));
177 
178  start_write_op(impl, offset,
179  buffer_sequence_adapter<asio::const_buffer,
180  ConstBufferSequence>::first(buffers), p.p);
181  p.v = p.p = 0;
182  }
183 
184  // Read some data. Returns the number of bytes received.
185  template <typename MutableBufferSequence>
186  size_t read_some(implementation_type& impl,
187  const MutableBufferSequence& buffers, asio::error_code& ec)
188  {
189  return read_some_at(impl, 0, buffers, ec);
190  }
191 
192  // Read some data at a specified offset. Returns the number of bytes received.
193  template <typename MutableBufferSequence>
194  size_t read_some_at(implementation_type& impl, uint64_t offset,
195  const MutableBufferSequence& buffers, asio::error_code& ec)
196  {
198  buffer_sequence_adapter<asio::mutable_buffer,
199  MutableBufferSequence>::first(buffers);
200 
201  return do_read(impl, offset, buffer, ec);
202  }
203 
204  // Start an asynchronous read. The buffer for the data being received must be
205  // valid for the lifetime of the asynchronous operation.
206  template <typename MutableBufferSequence, typename Handler>
207  void async_read_some(implementation_type& impl,
208  const MutableBufferSequence& buffers, Handler& handler)
209  {
210  // Allocate and construct an operation to wrap the handler.
211  typedef win_iocp_handle_read_op<MutableBufferSequence, Handler> op;
212  typename op::ptr p = { asio::detail::addressof(handler),
214  sizeof(op), handler), 0 };
215  p.p = new (p.v) op(buffers, handler);
216 
217  ASIO_HANDLER_CREATION((p.p, "handle", &impl, "async_read_some"));
218 
219  start_read_op(impl, 0,
220  buffer_sequence_adapter<asio::mutable_buffer,
221  MutableBufferSequence>::first(buffers), p.p);
222  p.v = p.p = 0;
223  }
224 
225  // Start an asynchronous read at a specified offset. The buffer for the data
226  // being received must be valid for the lifetime of the asynchronous
227  // operation.
228  template <typename MutableBufferSequence, typename Handler>
229  void async_read_some_at(implementation_type& impl, uint64_t offset,
230  const MutableBufferSequence& buffers, Handler& handler)
231  {
232  // Allocate and construct an operation to wrap the handler.
233  typedef win_iocp_handle_read_op<MutableBufferSequence, Handler> op;
234  typename op::ptr p = { asio::detail::addressof(handler),
236  sizeof(op), handler), 0 };
237  p.p = new (p.v) op(buffers, handler);
238 
239  ASIO_HANDLER_CREATION((p.p, "handle", &impl, "async_read_some_at"));
240 
241  start_read_op(impl, offset,
242  buffer_sequence_adapter<asio::mutable_buffer,
243  MutableBufferSequence>::first(buffers), p.p);
244  p.v = p.p = 0;
245  }
246 
247 private:
248  // Prevent the use of the null_buffers type with this service.
249  size_t write_some(implementation_type& impl,
250  const null_buffers& buffers, asio::error_code& ec);
251  size_t write_some_at(implementation_type& impl, uint64_t offset,
252  const null_buffers& buffers, asio::error_code& ec);
253  template <typename Handler>
254  void async_write_some(implementation_type& impl,
255  const null_buffers& buffers, Handler& handler);
256  template <typename Handler>
257  void async_write_some_at(implementation_type& impl, uint64_t offset,
258  const null_buffers& buffers, Handler& handler);
259  size_t read_some(implementation_type& impl,
260  const null_buffers& buffers, asio::error_code& ec);
261  size_t read_some_at(implementation_type& impl, uint64_t offset,
262  const null_buffers& buffers, asio::error_code& ec);
263  template <typename Handler>
264  void async_read_some(implementation_type& impl,
265  const null_buffers& buffers, Handler& handler);
266  template <typename Handler>
267  void async_read_some_at(implementation_type& impl, uint64_t offset,
268  const null_buffers& buffers, Handler& handler);
269 
270  // Helper class for waiting for synchronous operations to complete.
271  class overlapped_wrapper;
272 
273  // Helper function to perform a synchronous write operation.
274  ASIO_DECL size_t do_write(implementation_type& impl,
275  uint64_t offset, const asio::const_buffer& buffer,
276  asio::error_code& ec);
277 
278  // Helper function to start a write operation.
279  ASIO_DECL void start_write_op(implementation_type& impl,
280  uint64_t offset, const asio::const_buffer& buffer,
281  operation* op);
282 
283  // Helper function to perform a synchronous write operation.
284  ASIO_DECL size_t do_read(implementation_type& impl,
285  uint64_t offset, const asio::mutable_buffer& buffer,
286  asio::error_code& ec);
287 
288  // Helper function to start a read operation.
289  ASIO_DECL void start_read_op(implementation_type& impl,
290  uint64_t offset, const asio::mutable_buffer& buffer,
291  operation* op);
292 
293  // Update the ID of the thread from which cancellation is safe.
294  ASIO_DECL void update_cancellation_thread_id(implementation_type& impl);
295 
296  // Helper function to close a handle when the associated object is being
297  // destroyed.
298  ASIO_DECL void close_for_destruction(implementation_type& impl);
299 
300  // The IOCP service used for running asynchronous operations and dispatching
301  // handlers.
302  win_iocp_io_service& iocp_service_;
303 
304  // Mutex to protect access to the linked list of implementations.
305  mutex mutex_;
306 
307  // The head of a linked list of all implementations.
308  implementation_type* impl_list_;
309 };
310 
311 } // namespace detail
312 } // namespace asio
313 
315 
316 #if defined(ASIO_HEADER_ONLY)
318 #endif // defined(ASIO_HEADER_ONLY)
319 
320 #endif // defined(ASIO_HAS_IOCP)
321 
322 #endif // ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP
Provides core I/O functionality.
Definition: io_service.hpp:184
Holds a buffer that cannot be modified.
Definition: buffer.hpp:211
null_mutex mutex
Definition: mutex.hpp:36
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Definition: buffer.hpp:706
uint64_t offset
Definition: read_at.hpp:571
const MutableBufferSequence & buffers
Definition: read.hpp:521
Holds a buffer that can be modified.
Definition: buffer.hpp:91
Class to represent an error code value.
Definition: error_code.hpp:80
#define ASIO_DECL
Definition: config.hpp:43
task_io_service_operation operation
Definition: operation.hpp:32
ASIO_DECL int close(int d, state_type &state, asio::error_code &ec)
void * allocate(std::size_t s, Handler &h)
#define ASIO_HANDLER_CREATION(args)