1 // 2 // detail/posix_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_POSIX_FD_SET_ADAPTER_HPP 12 #define ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP 13 14 15 #include "asio/detail/config.hpp" 16 17 18 #include <cstring> 19 #include "asio/detail/noncopyable.hpp" 20 #include "asio/detail/reactor_op_queue.hpp" 21 #include "asio/detail/socket_types.hpp" 22 23 #include "asio/detail/push_options.hpp" 24 25 namespace asio { 26 namespace detail { 27 28 // Adapts the FD_SET type to meet the Descriptor_Set concept's requirements. 29 class posix_fd_set_adapter : noncopyable 30 { 31 public: 32 posix_fd_set_adapter() 33 : max_descriptor_(invalid_socket) 34 { 35 using namespace std; // Needed for memset on Solaris. 36 FD_ZERO(&fd_set_); 37 } 38 39 void reset() 40 { 41 using namespace std; // Needed for memset on Solaris. 42 FD_ZERO(&fd_set_); 43 } 44 45 bool set(socket_type descriptor) 46 { 47 if (descriptor < (socket_type)FD_SETSIZE) 48 { 49 if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_) 50 max_descriptor_ = descriptor; 51 FD_SET(descriptor, &fd_set_); 52 return true; 53 } 54 return false; 55 } 56 57 void set(reactor_op_queue<socket_type>& operations, op_queue<operation>& ops) 58 { 59 reactor_op_queue<socket_type>::iterator i = operations.begin(); 60 while (i != operations.end()) 61 { 62 reactor_op_queue<socket_type>::iterator op_iter = i++; 63 if (!set(op_iter->first)) 64 { 65 asio::error_code ec(error::fd_set_failure); 66 operations.cancel_operations(op_iter, ops, ec); 67 } 68 } 69 } 70 71 bool is_set(socket_type descriptor) const 72 { 73 return FD_ISSET(descriptor, &fd_set_) != 0; 74 } 75 76 operator fd_set*() 77 { 78 return &fd_set_; 79 } 80 81 socket_type max_descriptor() const 82 { 83 return max_descriptor_; 84 } 85 86 void perform(reactor_op_queue<socket_type>& operations, 87 op_queue<operation>& ops) const 88 { 89 reactor_op_queue<socket_type>::iterator i = operations.begin(); 90 while (i != operations.end()) 91 { 92 reactor_op_queue<socket_type>::iterator op_iter = i++; 93 if (is_set(op_iter->first)) 94 operations.perform_operations(op_iter, ops); 95 } 96 } 97 98 private: 99 mutable fd_set fd_set_; 100 socket_type max_descriptor_; 101 }; 102 103 } // namespace detail 104 } // namespace asio 105 106 #include "asio/detail/pop_options.hpp" 107 108 // && !defined(__CYGWIN__) 109 // && !defined(ASIO_WINDOWS_RUNTIME) 110 111 #endif // ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP 112