Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / asio / detail / impl / socket_select_interrupter.ipp @ 2486

History | View | Annotate | Download (5.5 kB)

1 2486 sjacqu01
//
2 2486 sjacqu01
// detail/impl/socket_select_interrupter.ipp
3 2486 sjacqu01
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 2486 sjacqu01
//
5 2486 sjacqu01
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 2486 sjacqu01
//
7 2486 sjacqu01
// Distributed under the Boost Software License, Version 1.0. (See accompanying
8 2486 sjacqu01
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 2486 sjacqu01
//
10 2486 sjacqu01
11 2486 sjacqu01
#ifndef BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP
12 2486 sjacqu01
#define BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP
13 2486 sjacqu01
14 2486 sjacqu01
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 2486 sjacqu01
# pragma once
16 2486 sjacqu01
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 2486 sjacqu01
18 2486 sjacqu01
#include <boost/asio/detail/config.hpp>
19 2486 sjacqu01
20 2486 sjacqu01
#if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
21 2486 sjacqu01
22 2486 sjacqu01
#if defined(BOOST_ASIO_WINDOWS) \
23 2486 sjacqu01
  || defined(__CYGWIN__) \
24 2486 sjacqu01
  || defined(__SYMBIAN32__)
25 2486 sjacqu01
26 2486 sjacqu01
#include <cstdlib>
27 2486 sjacqu01
#include <boost/asio/detail/socket_holder.hpp>
28 2486 sjacqu01
#include <boost/asio/detail/socket_ops.hpp>
29 2486 sjacqu01
#include <boost/asio/detail/socket_select_interrupter.hpp>
30 2486 sjacqu01
#include <boost/asio/detail/throw_error.hpp>
31 2486 sjacqu01
#include <boost/asio/error.hpp>
32 2486 sjacqu01
33 2486 sjacqu01
#include <boost/asio/detail/push_options.hpp>
34 2486 sjacqu01
35 2486 sjacqu01
namespace boost {
36 2486 sjacqu01
namespace asio {
37 2486 sjacqu01
namespace detail {
38 2486 sjacqu01
39 2486 sjacqu01
socket_select_interrupter::socket_select_interrupter()
40 2486 sjacqu01
{
41 2486 sjacqu01
  open_descriptors();
42 2486 sjacqu01
}
43 2486 sjacqu01
44 2486 sjacqu01
void socket_select_interrupter::open_descriptors()
45 2486 sjacqu01
{
46 2486 sjacqu01
  boost::system::error_code ec;
47 2486 sjacqu01
  socket_holder acceptor(socket_ops::socket(
48 2486 sjacqu01
        AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
49 2486 sjacqu01
  if (acceptor.get() == invalid_socket)
50 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
51 2486 sjacqu01
52 2486 sjacqu01
  int opt = 1;
53 2486 sjacqu01
  socket_ops::state_type acceptor_state = 0;
54 2486 sjacqu01
  socket_ops::setsockopt(acceptor.get(), acceptor_state,
55 2486 sjacqu01
      SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec);
56 2486 sjacqu01
57 2486 sjacqu01
  using namespace std; // For memset.
58 2486 sjacqu01
  sockaddr_in4_type addr;
59 2486 sjacqu01
  std::size_t addr_len = sizeof(addr);
60 2486 sjacqu01
  memset(&addr, 0, sizeof(addr));
61 2486 sjacqu01
  addr.sin_family = AF_INET;
62 2486 sjacqu01
  addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK);
63 2486 sjacqu01
  addr.sin_port = 0;
64 2486 sjacqu01
  if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr,
65 2486 sjacqu01
        addr_len, ec) == socket_error_retval)
66 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
67 2486 sjacqu01
68 2486 sjacqu01
  if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr,
69 2486 sjacqu01
        &addr_len, ec) == socket_error_retval)
70 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
71 2486 sjacqu01
72 2486 sjacqu01
  // Some broken firewalls on Windows will intermittently cause getsockname to
73 2486 sjacqu01
  // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We
74 2486 sjacqu01
  // explicitly specify the target address here to work around this problem.
75 2486 sjacqu01
  addr.sin_addr.s_addr = socket_ops::host_to_network_long(INADDR_LOOPBACK);
76 2486 sjacqu01
77 2486 sjacqu01
  if (socket_ops::listen(acceptor.get(),
78 2486 sjacqu01
        SOMAXCONN, ec) == socket_error_retval)
79 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
80 2486 sjacqu01
81 2486 sjacqu01
  socket_holder client(socket_ops::socket(
82 2486 sjacqu01
        AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
83 2486 sjacqu01
  if (client.get() == invalid_socket)
84 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
85 2486 sjacqu01
86 2486 sjacqu01
  if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr,
87 2486 sjacqu01
        addr_len, ec) == socket_error_retval)
88 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
89 2486 sjacqu01
90 2486 sjacqu01
  socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec));
91 2486 sjacqu01
  if (server.get() == invalid_socket)
92 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
93 2486 sjacqu01
94 2486 sjacqu01
  ioctl_arg_type non_blocking = 1;
95 2486 sjacqu01
  socket_ops::state_type client_state = 0;
96 2486 sjacqu01
  if (socket_ops::ioctl(client.get(), client_state,
97 2486 sjacqu01
        FIONBIO, &non_blocking, ec))
98 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
99 2486 sjacqu01
100 2486 sjacqu01
  opt = 1;
101 2486 sjacqu01
  socket_ops::setsockopt(client.get(), client_state,
102 2486 sjacqu01
      IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
103 2486 sjacqu01
104 2486 sjacqu01
  non_blocking = 1;
105 2486 sjacqu01
  socket_ops::state_type server_state = 0;
106 2486 sjacqu01
  if (socket_ops::ioctl(server.get(), server_state,
107 2486 sjacqu01
        FIONBIO, &non_blocking, ec))
108 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "socket_select_interrupter");
109 2486 sjacqu01
110 2486 sjacqu01
  opt = 1;
111 2486 sjacqu01
  socket_ops::setsockopt(server.get(), server_state,
112 2486 sjacqu01
      IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
113 2486 sjacqu01
114 2486 sjacqu01
  read_descriptor_ = server.release();
115 2486 sjacqu01
  write_descriptor_ = client.release();
116 2486 sjacqu01
}
117 2486 sjacqu01
118 2486 sjacqu01
socket_select_interrupter::~socket_select_interrupter()
119 2486 sjacqu01
{
120 2486 sjacqu01
  close_descriptors();
121 2486 sjacqu01
}
122 2486 sjacqu01
123 2486 sjacqu01
void socket_select_interrupter::close_descriptors()
124 2486 sjacqu01
{
125 2486 sjacqu01
  boost::system::error_code ec;
126 2486 sjacqu01
  socket_ops::state_type state = socket_ops::internal_non_blocking;
127 2486 sjacqu01
  if (read_descriptor_ != invalid_socket)
128 2486 sjacqu01
    socket_ops::close(read_descriptor_, state, true, ec);
129 2486 sjacqu01
  if (write_descriptor_ != invalid_socket)
130 2486 sjacqu01
    socket_ops::close(write_descriptor_, state, true, ec);
131 2486 sjacqu01
}
132 2486 sjacqu01
133 2486 sjacqu01
void socket_select_interrupter::recreate()
134 2486 sjacqu01
{
135 2486 sjacqu01
  close_descriptors();
136 2486 sjacqu01
137 2486 sjacqu01
  write_descriptor_ = invalid_socket;
138 2486 sjacqu01
  read_descriptor_ = invalid_socket;
139 2486 sjacqu01
140 2486 sjacqu01
  open_descriptors();
141 2486 sjacqu01
}
142 2486 sjacqu01
143 2486 sjacqu01
void socket_select_interrupter::interrupt()
144 2486 sjacqu01
{
145 2486 sjacqu01
  char byte = 0;
146 2486 sjacqu01
  socket_ops::buf b;
147 2486 sjacqu01
  socket_ops::init_buf(b, &byte, 1);
148 2486 sjacqu01
  boost::system::error_code ec;
149 2486 sjacqu01
  socket_ops::send(write_descriptor_, &b, 1, 0, ec);
150 2486 sjacqu01
}
151 2486 sjacqu01
152 2486 sjacqu01
bool socket_select_interrupter::reset()
153 2486 sjacqu01
{
154 2486 sjacqu01
  char data[1024];
155 2486 sjacqu01
  socket_ops::buf b;
156 2486 sjacqu01
  socket_ops::init_buf(b, data, sizeof(data));
157 2486 sjacqu01
  boost::system::error_code ec;
158 2486 sjacqu01
  int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
159 2486 sjacqu01
  bool was_interrupted = (bytes_read > 0);
160 2486 sjacqu01
  while (bytes_read == sizeof(data))
161 2486 sjacqu01
    bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
162 2486 sjacqu01
  return was_interrupted;
163 2486 sjacqu01
}
164 2486 sjacqu01
165 2486 sjacqu01
} // namespace detail
166 2486 sjacqu01
} // namespace asio
167 2486 sjacqu01
} // namespace boost
168 2486 sjacqu01
169 2486 sjacqu01
#include <boost/asio/detail/pop_options.hpp>
170 2486 sjacqu01
171 2486 sjacqu01
#endif // defined(BOOST_ASIO_WINDOWS)
172 2486 sjacqu01
       // || defined(__CYGWIN__)
173 2486 sjacqu01
       // || defined(__SYMBIAN32__)
174 2486 sjacqu01
175 2486 sjacqu01
#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
176 2486 sjacqu01
177 2486 sjacqu01
#endif // BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP