Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / asio / detail / win_fd_set_adapter.hpp @ 2486

History | View | Annotate | Download (3.8 kB)

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 BOOST_ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP
12
#define BOOST_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 <boost/asio/detail/config.hpp>
19

    
20
#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
21

    
22
#include <boost/asio/detail/noncopyable.hpp>
23
#include <boost/asio/detail/reactor_op_queue.hpp>
24
#include <boost/asio/detail/socket_types.hpp>
25

    
26
#include <boost/asio/detail/push_options.hpp>
27

    
28
namespace boost {
29
namespace asio {
30
namespace detail {
31

    
32
// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements.
33
class win_fd_set_adapter : noncopyable
34
{
35
public:
36
  enum { default_fd_set_size = 1024 };
37

    
38
  win_fd_set_adapter()
39
    : capacity_(default_fd_set_size),
40
      max_descriptor_(invalid_socket)
41
  {
42
    fd_set_ = static_cast<win_fd_set*>(::operator new(
43
          sizeof(win_fd_set) - sizeof(SOCKET)
44
          + sizeof(SOCKET) * (capacity_)));
45
    fd_set_->fd_count = 0;
46
  }
47

    
48
  ~win_fd_set_adapter()
49
  {
50
    ::operator delete(fd_set_);
51
  }
52

    
53
  void reset()
54
  {
55
    fd_set_->fd_count = 0;
56
    max_descriptor_ = invalid_socket;
57
  }
58

    
59
  bool set(socket_type descriptor)
60
  {
61
    for (u_int i = 0; i < fd_set_->fd_count; ++i)
62
      if (fd_set_->fd_array[i] == descriptor)
63
        return true;
64

    
65
    reserve(fd_set_->fd_count + 1);
66
    fd_set_->fd_array[fd_set_->fd_count++] = descriptor;
67
    return true;
68
  }
69

    
70
  void set(reactor_op_queue<socket_type>& operations, op_queue<operation>&)
71
  {
72
    reactor_op_queue<socket_type>::iterator i = operations.begin();
73
    while (i != operations.end())
74
    {
75
      reactor_op_queue<socket_type>::iterator op_iter = i++;
76
      reserve(fd_set_->fd_count + 1);
77
      fd_set_->fd_array[fd_set_->fd_count++] = op_iter->first;
78
    }
79
  }
80

    
81
  bool is_set(socket_type descriptor) const
82
  {
83
    return !!__WSAFDIsSet(descriptor,
84
        const_cast<fd_set*>(reinterpret_cast<const fd_set*>(fd_set_)));
85
  }
86

    
87
  operator fd_set*()
88
  {
89
    return reinterpret_cast<fd_set*>(fd_set_);
90
  }
91

    
92
  socket_type max_descriptor() const
93
  {
94
    return max_descriptor_;
95
  }
96

    
97
  void perform(reactor_op_queue<socket_type>& operations,
98
      op_queue<operation>& ops) const
99
  {
100
    for (u_int i = 0; i < fd_set_->fd_count; ++i)
101
      operations.perform_operations(fd_set_->fd_array[i], ops);
102
  }
103

    
104
private:
105
  // This structure is defined to be compatible with the Windows API fd_set
106
  // structure, but without being dependent on the value of FD_SETSIZE. We use
107
  // the "struct hack" to allow the number of descriptors to be varied at
108
  // runtime.
109
  struct win_fd_set
110
  {
111
    u_int fd_count;
112
    SOCKET fd_array[1];
113
  };
114

    
115
  // Increase the fd_set_ capacity to at least the specified number of elements.
116
  void reserve(u_int n)
117
  {
118
    if (n <= capacity_)
119
      return;
120

    
121
    u_int new_capacity = capacity_ + capacity_ / 2;
122
    if (new_capacity < n)
123
      new_capacity = n;
124

    
125
    win_fd_set* new_fd_set = static_cast<win_fd_set*>(::operator new(
126
          sizeof(win_fd_set) - sizeof(SOCKET)
127
          + sizeof(SOCKET) * (new_capacity)));
128

    
129
    new_fd_set->fd_count = fd_set_->fd_count;
130
    for (u_int i = 0; i < fd_set_->fd_count; ++i)
131
      new_fd_set->fd_array[i] = fd_set_->fd_array[i];
132

    
133
    ::operator delete(fd_set_);
134
    fd_set_ = new_fd_set;
135
    capacity_ = new_capacity;
136
  }
137

    
138
  win_fd_set* fd_set_;
139
  u_int capacity_;
140
  socket_type max_descriptor_;
141
};
142

    
143
} // namespace detail
144
} // namespace asio
145
} // namespace boost
146

    
147
#include <boost/asio/detail/pop_options.hpp>
148

    
149
#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
150

    
151
#endif // BOOST_ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP