Home | History | Annotate | Download | only in detail
      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