pipe_select_interrupter.hpp
Go to the documentation of this file.
00001 //
00002 // pipe_select_interrupter.hpp
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
00004 //
00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00006 //
00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 
00011 #ifndef ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP
00012 #define ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP
00013 
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017 
00018 #include "asio/detail/push_options.hpp"
00019 
00020 #include "asio/detail/push_options.hpp"
00021 #include <boost/config.hpp>
00022 #include <boost/throw_exception.hpp>
00023 #include "asio/detail/pop_options.hpp"
00024 
00025 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
00026 
00027 #include "asio/detail/push_options.hpp"
00028 #include <fcntl.h>
00029 #include "asio/detail/pop_options.hpp"
00030 
00031 #include "asio/error.hpp"
00032 #include "asio/system_error.hpp"
00033 #include "asio/detail/socket_types.hpp"
00034 
00035 namespace asio {
00036 namespace detail {
00037 
00038 class pipe_select_interrupter
00039 {
00040 public:
00041   // Constructor.
00042   pipe_select_interrupter()
00043   {
00044     int pipe_fds[2];
00045     if (pipe(pipe_fds) == 0)
00046     {
00047       read_descriptor_ = pipe_fds[0];
00048       ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
00049       write_descriptor_ = pipe_fds[1];
00050       ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
00051     }
00052     else
00053     {
00054       asio::error_code ec(errno,
00055           asio::error::get_system_category());
00056       asio::system_error e(ec, "pipe_select_interrupter");
00057       boost::throw_exception(e);
00058     }
00059   }
00060 
00061   // Destructor.
00062   ~pipe_select_interrupter()
00063   {
00064     if (read_descriptor_ != -1)
00065       ::close(read_descriptor_);
00066     if (write_descriptor_ != -1)
00067       ::close(write_descriptor_);
00068   }
00069 
00070   // Interrupt the select call.
00071   void interrupt()
00072   {
00073     char byte = 0;
00074     if (::write(write_descriptor_, &byte, 1) == -1) {
00075                 // do nothing
00076         }
00077   }
00078 
00079   // Reset the select interrupt. Returns true if the call was interrupted.
00080   bool reset()
00081   {
00082     char data[1024];
00083     int bytes_read = ::read(read_descriptor_, data, sizeof(data));
00084     bool was_interrupted = (bytes_read > 0);
00085     while (bytes_read == sizeof(data))
00086       bytes_read = ::read(read_descriptor_, data, sizeof(data));
00087     return was_interrupted;
00088   }
00089 
00090   // Get the read descriptor to be passed to select.
00091   int read_descriptor() const
00092   {
00093     return read_descriptor_;
00094   }
00095 
00096 private:
00097   // The read end of a connection used to interrupt the select call. This file
00098   // descriptor is passed to select such that when it is time to stop, a single
00099   // byte will be written on the other end of the connection and this
00100   // descriptor will become readable.
00101   int read_descriptor_;
00102 
00103   // The write end of a connection used to interrupt the select call. A single
00104   // byte may be written to this to wake up the select which is waiting for the
00105   // other end to become readable.
00106   int write_descriptor_;
00107 };
00108 
00109 } // namespace detail
00110 } // namespace asio
00111 
00112 #endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
00113 
00114 #include "asio/detail/pop_options.hpp"
00115 
00116 #endif // ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39