10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// detail/posix_fd_set_adapter.hpp
30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying
80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie//
100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP
120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP
130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp"
160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include <cstring>
190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/noncopyable.hpp"
200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/reactor_op_queue.hpp"
210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/socket_types.hpp"
220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp"
240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio {
260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail {
270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Adapts the FD_SET type to meet the Descriptor_Set concept's requirements.
290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass posix_fd_set_adapter : noncopyable
300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{
310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic:
320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  posix_fd_set_adapter()
330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    : max_descriptor_(invalid_socket)
340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    using namespace std; // Needed for memset on Solaris.
360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    FD_ZERO(&fd_set_);
370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void reset()
400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    using namespace std; // Needed for memset on Solaris.
420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    FD_ZERO(&fd_set_);
430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  bool set(socket_type descriptor)
460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    if (descriptor < (socket_type)FD_SETSIZE)
480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    {
490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      if (max_descriptor_ == invalid_socket || descriptor > max_descriptor_)
500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie        max_descriptor_ = descriptor;
510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      FD_SET(descriptor, &fd_set_);
520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      return true;
530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    }
540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return false;
550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void set(reactor_op_queue<socket_type>& operations, op_queue<operation>& ops)
580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    reactor_op_queue<socket_type>::iterator i = operations.begin();
600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    while (i != operations.end())
610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    {
620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      reactor_op_queue<socket_type>::iterator op_iter = i++;
630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      if (!set(op_iter->first))
640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      {
650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie        asio::error_code ec(error::fd_set_failure);
660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie        operations.cancel_operations(op_iter, ops, ec);
670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      }
680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    }
690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  bool is_set(socket_type descriptor) const
720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return FD_ISSET(descriptor, &fd_set_) != 0;
740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  operator fd_set*()
770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return &fd_set_;
790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  socket_type max_descriptor() const
820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    return max_descriptor_;
840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  void perform(reactor_op_queue<socket_type>& operations,
870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      op_queue<operation>& ops) const
880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  {
890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    reactor_op_queue<socket_type>::iterator i = operations.begin();
900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    while (i != operations.end())
910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    {
920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      reactor_op_queue<socket_type>::iterator op_iter = i++;
930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie      if (is_set(op_iter->first))
940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie        operations.perform_operations(op_iter, ops);
950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie    }
960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  }
970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate:
990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  mutable fd_set fd_set_;
1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie  socket_type max_descriptor_;
1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie};
1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace detail
1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio
1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp"
1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie       // && !defined(__CYGWIN__)
1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie       // && !defined(ASIO_WINDOWS_RUNTIME)
1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie
1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP
112