diff options
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp b/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp index 8636a91..afb40d0 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_fd_set_adapter.hpp @@ -2,7 +2,7 @@ // detail/win_fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -19,6 +19,7 @@ #if defined(BOOST_WINDOWS) || defined(__CYGWIN__) +#include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/push_options.hpp> @@ -28,39 +29,67 @@ namespace asio { namespace detail { // Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. -class win_fd_set_adapter +class win_fd_set_adapter : noncopyable { public: - enum { win_fd_set_size = 1024 }; + enum { default_fd_set_size = 1024 }; win_fd_set_adapter() - : max_descriptor_(invalid_socket) + : capacity_(default_fd_set_size), + max_descriptor_(invalid_socket) { - fd_set_.fd_count = 0; + fd_set_ = static_cast<win_fd_set*>(::operator new( + sizeof(win_fd_set) - sizeof(SOCKET) + + sizeof(SOCKET) * (capacity_))); + fd_set_->fd_count = 0; + } + + ~win_fd_set_adapter() + { + ::operator delete(fd_set_); + } + + void reset() + { + fd_set_->fd_count = 0; + max_descriptor_ = invalid_socket; } bool set(socket_type descriptor) { - for (u_int i = 0; i < fd_set_.fd_count; ++i) - if (fd_set_.fd_array[i] == descriptor) + for (u_int i = 0; i < fd_set_->fd_count; ++i) + if (fd_set_->fd_array[i] == descriptor) return true; - if (fd_set_.fd_count < win_fd_set_size) + + if (fd_set_->fd_count == capacity_) { - fd_set_.fd_array[fd_set_.fd_count++] = descriptor; - return true; + u_int new_capacity = capacity_ + capacity_ / 2; + win_fd_set* new_fd_set = static_cast<win_fd_set*>(::operator new( + sizeof(win_fd_set) - sizeof(SOCKET) + + sizeof(SOCKET) * (new_capacity))); + + new_fd_set->fd_count = fd_set_->fd_count; + for (u_int i = 0; i < fd_set_->fd_count; ++i) + new_fd_set->fd_array[i] = fd_set_->fd_array[i]; + + ::operator delete(fd_set_); + fd_set_ = new_fd_set; + capacity_ = new_capacity; } - return false; + + fd_set_->fd_array[fd_set_->fd_count++] = descriptor; + return true; } bool is_set(socket_type descriptor) const { return !!__WSAFDIsSet(descriptor, - const_cast<fd_set*>(reinterpret_cast<const fd_set*>(&fd_set_))); + const_cast<fd_set*>(reinterpret_cast<const fd_set*>(fd_set_))); } operator fd_set*() { - return reinterpret_cast<fd_set*>(&fd_set_); + return reinterpret_cast<fd_set*>(fd_set_); } socket_type max_descriptor() const @@ -69,15 +98,19 @@ public: } private: + // This structure is defined to be compatible with the Windows API fd_set - // structure, but without being dependent on the value of FD_SETSIZE. + // structure, but without being dependent on the value of FD_SETSIZE. We use + // the "struct hack" to allow the number of descriptors to be varied at + // runtime. struct win_fd_set { u_int fd_count; - SOCKET fd_array[win_fd_set_size]; + SOCKET fd_array[1]; }; - win_fd_set fd_set_; + win_fd_set* fd_set_; + u_int capacity_; socket_type max_descriptor_; }; |