2
// pipe_select_interrupter.hpp
3
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11
#ifndef ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP
12
#define ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
#include "asio/detail/push_options.hpp"
20
#include "asio/detail/push_options.hpp"
21
#include <boost/config.hpp>
22
#include <boost/throw_exception.hpp>
23
#include "asio/detail/pop_options.hpp"
25
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
27
#include "asio/detail/push_options.hpp"
29
#include "asio/detail/pop_options.hpp"
31
#include "asio/error.hpp"
32
#include "asio/system_error.hpp"
33
#include "asio/detail/socket_types.hpp"
38
class pipe_select_interrupter
42
pipe_select_interrupter()
45
if (pipe(pipe_fds) == 0)
47
read_descriptor_ = pipe_fds[0];
48
::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
49
write_descriptor_ = pipe_fds[1];
50
::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
54
asio::error_code ec(errno,
55
asio::error::get_system_category());
56
asio::system_error e(ec, "pipe_select_interrupter");
57
boost::throw_exception(e);
62
~pipe_select_interrupter()
64
if (read_descriptor_ != -1)
65
::close(read_descriptor_);
66
if (write_descriptor_ != -1)
67
::close(write_descriptor_);
70
// Interrupt the select call.
74
::write(write_descriptor_, &byte, 1);
77
// Reset the select interrupt. Returns true if the call was interrupted.
81
int bytes_read = ::read(read_descriptor_, data, sizeof(data));
82
bool was_interrupted = (bytes_read > 0);
83
while (bytes_read == sizeof(data))
84
bytes_read = ::read(read_descriptor_, data, sizeof(data));
85
return was_interrupted;
88
// Get the read descriptor to be passed to select.
89
int read_descriptor() const
91
return read_descriptor_;
95
// The read end of a connection used to interrupt the select call. This file
96
// descriptor is passed to select such that when it is time to stop, a single
97
// byte will be written on the other end of the connection and this
98
// descriptor will become readable.
101
// The write end of a connection used to interrupt the select call. A single
102
// byte may be written to this to wake up the select which is waiting for the
103
// other end to become readable.
104
int write_descriptor_;
107
} // namespace detail
110
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
112
#include "asio/detail/pop_options.hpp"
114
#endif // ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP