Chris@16: // Chris@16: // detail/impl/pipe_select_interrupter.ipp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP Chris@16: #define BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: Chris@16: #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) Chris@16: #if !defined(BOOST_ASIO_WINDOWS) Chris@16: #if !defined(__CYGWIN__) Chris@16: #if !defined(__SYMBIAN32__) Chris@16: #if !defined(BOOST_ASIO_HAS_EVENTFD) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@16: pipe_select_interrupter::pipe_select_interrupter() Chris@16: { Chris@16: open_descriptors(); Chris@16: } Chris@16: Chris@16: void pipe_select_interrupter::open_descriptors() Chris@16: { Chris@16: int pipe_fds[2]; Chris@16: if (pipe(pipe_fds) == 0) Chris@16: { Chris@16: read_descriptor_ = pipe_fds[0]; Chris@16: ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK); Chris@16: write_descriptor_ = pipe_fds[1]; Chris@16: ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK); Chris@16: Chris@16: #if defined(FD_CLOEXEC) Chris@16: ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC); Chris@16: ::fcntl(write_descriptor_, F_SETFD, FD_CLOEXEC); Chris@16: #endif // defined(FD_CLOEXEC) Chris@16: } Chris@16: else Chris@16: { Chris@16: boost::system::error_code ec(errno, Chris@16: boost::asio::error::get_system_category()); Chris@16: boost::asio::detail::throw_error(ec, "pipe_select_interrupter"); Chris@16: } Chris@16: } Chris@16: Chris@16: pipe_select_interrupter::~pipe_select_interrupter() Chris@16: { Chris@16: close_descriptors(); Chris@16: } Chris@16: Chris@16: void pipe_select_interrupter::close_descriptors() Chris@16: { Chris@16: if (read_descriptor_ != -1) Chris@16: ::close(read_descriptor_); Chris@16: if (write_descriptor_ != -1) Chris@16: ::close(write_descriptor_); Chris@16: } Chris@16: Chris@16: void pipe_select_interrupter::recreate() Chris@16: { Chris@16: close_descriptors(); Chris@16: Chris@16: write_descriptor_ = -1; Chris@16: read_descriptor_ = -1; Chris@16: Chris@16: open_descriptors(); Chris@16: } Chris@16: Chris@16: void pipe_select_interrupter::interrupt() Chris@16: { Chris@16: char byte = 0; Chris@16: signed_size_type result = ::write(write_descriptor_, &byte, 1); Chris@16: (void)result; Chris@16: } Chris@16: Chris@16: bool pipe_select_interrupter::reset() Chris@16: { Chris@16: for (;;) Chris@16: { Chris@16: char data[1024]; Chris@16: signed_size_type bytes_read = ::read(read_descriptor_, data, sizeof(data)); Chris@16: if (bytes_read < 0 && errno == EINTR) Chris@16: continue; Chris@16: bool was_interrupted = (bytes_read > 0); Chris@16: while (bytes_read == sizeof(data)) Chris@16: bytes_read = ::read(read_descriptor_, data, sizeof(data)); Chris@16: return was_interrupted; Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // !defined(BOOST_ASIO_HAS_EVENTFD) Chris@16: #endif // !defined(__SYMBIAN32__) Chris@16: #endif // !defined(__CYGWIN__) Chris@16: #endif // !defined(BOOST_ASIO_WINDOWS) Chris@16: #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP