Realistic 3D camera system
3D camera system components
win_fd_set_adapter.hpp
Go to the documentation of this file.
1 //
2 // detail/win_fd_set_adapter.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_WIN_FD_SET_ADAPTER_HPP
12 #define ASIO_DETAIL_WIN_FD_SET_ADAPTER_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_WINDOWS) || defined(__CYGWIN__)
21 
25 
27 
28 namespace asio {
29 namespace detail {
30 
31 // Adapts the FD_SET type to meet the Descriptor_Set concept's requirements.
32 class win_fd_set_adapter : noncopyable
33 {
34 public:
35  enum { default_fd_set_size = 1024 };
36 
37  win_fd_set_adapter()
38  : capacity_(default_fd_set_size),
39  max_descriptor_(invalid_socket)
40  {
41  fd_set_ = static_cast<win_fd_set*>(::operator new(
42  sizeof(win_fd_set) - sizeof(SOCKET)
43  + sizeof(SOCKET) * (capacity_)));
44  fd_set_->fd_count = 0;
45  }
46 
47  ~win_fd_set_adapter()
48  {
49  ::operator delete(fd_set_);
50  }
51 
52  void reset()
53  {
54  fd_set_->fd_count = 0;
55  max_descriptor_ = invalid_socket;
56  }
57 
58  bool set(socket_type descriptor)
59  {
60  for (u_int i = 0; i < fd_set_->fd_count; ++i)
61  if (fd_set_->fd_array[i] == descriptor)
62  return true;
63 
64  reserve(fd_set_->fd_count + 1);
65  fd_set_->fd_array[fd_set_->fd_count++] = descriptor;
66  return true;
67  }
68 
69  void set(reactor_op_queue<socket_type>& operations, op_queue<operation>&)
70  {
71  reactor_op_queue<socket_type>::iterator i = operations.begin();
72  while (i != operations.end())
73  {
75  reserve(fd_set_->fd_count + 1);
76  fd_set_->fd_array[fd_set_->fd_count++] = op_iter->first;
77  }
78  }
79 
80  bool is_set(socket_type descriptor) const
81  {
82  return !!__WSAFDIsSet(descriptor,
83  const_cast<fd_set*>(reinterpret_cast<const fd_set*>(fd_set_)));
84  }
85 
86  operator fd_set*()
87  {
88  return reinterpret_cast<fd_set*>(fd_set_);
89  }
90 
91  socket_type max_descriptor() const
92  {
93  return max_descriptor_;
94  }
95 
96  void perform(reactor_op_queue<socket_type>& operations,
97  op_queue<operation>& ops) const
98  {
99  for (u_int i = 0; i < fd_set_->fd_count; ++i)
100  operations.perform_operations(fd_set_->fd_array[i], ops);
101  }
102 
103 private:
104  // This structure is defined to be compatible with the Windows API fd_set
105  // structure, but without being dependent on the value of FD_SETSIZE. We use
106  // the "struct hack" to allow the number of descriptors to be varied at
107  // runtime.
108  struct win_fd_set
109  {
110  u_int fd_count;
111  SOCKET fd_array[1];
112  };
113 
114  // Increase the fd_set_ capacity to at least the specified number of elements.
115  void reserve(u_int n)
116  {
117  if (n <= capacity_)
118  return;
119 
120  u_int new_capacity = capacity_ + capacity_ / 2;
121  if (new_capacity < n)
122  new_capacity = n;
123 
124  win_fd_set* new_fd_set = static_cast<win_fd_set*>(::operator new(
125  sizeof(win_fd_set) - sizeof(SOCKET)
126  + sizeof(SOCKET) * (new_capacity)));
127 
128  new_fd_set->fd_count = fd_set_->fd_count;
129  for (u_int i = 0; i < fd_set_->fd_count; ++i)
130  new_fd_set->fd_array[i] = fd_set_->fd_array[i];
131 
132  ::operator delete(fd_set_);
133  fd_set_ = new_fd_set;
134  capacity_ = new_capacity;
135  }
136 
137  win_fd_set* fd_set_;
138  u_int capacity_;
139  socket_type max_descriptor_;
140 };
141 
142 } // namespace detail
143 } // namespace asio
144 
146 
147 #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
148 
149 #endif // ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP
const int invalid_socket
hash_map< key_type, mapped_type >::iterator iterator