/Src/Dependencies/Boost/boost/asio/detail/impl/pipe_select_interrupter.ipp

http://hadesmem.googlecode.com/ · C++ Header · 123 lines · 93 code · 21 blank · 9 comment · 13 complexity · 1620c6ab75624f153a64c0b8affe2d8c MD5 · raw file

  1. //
  2. // detail/impl/pipe_select_interrupter.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  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)
  9. //
  10. #ifndef BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP
  11. #define BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #if !defined(BOOST_WINDOWS)
  17. #if !defined(__CYGWIN__)
  18. #if !defined(__SYMBIAN32__)
  19. #if !defined(BOOST_ASIO_HAS_EVENTFD)
  20. #include <fcntl.h>
  21. #include <sys/stat.h>
  22. #include <sys/types.h>
  23. #include <unistd.h>
  24. #include <boost/asio/detail/pipe_select_interrupter.hpp>
  25. #include <boost/asio/detail/throw_error.hpp>
  26. #include <boost/asio/error.hpp>
  27. #include <boost/asio/detail/push_options.hpp>
  28. namespace boost {
  29. namespace asio {
  30. namespace detail {
  31. pipe_select_interrupter::pipe_select_interrupter()
  32. {
  33. open_descriptors();
  34. }
  35. void pipe_select_interrupter::open_descriptors()
  36. {
  37. int pipe_fds[2];
  38. if (pipe(pipe_fds) == 0)
  39. {
  40. read_descriptor_ = pipe_fds[0];
  41. ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
  42. write_descriptor_ = pipe_fds[1];
  43. ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
  44. #if defined(FD_CLOEXEC)
  45. ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
  46. ::fcntl(write_descriptor_, F_SETFD, FD_CLOEXEC);
  47. #endif // defined(FD_CLOEXEC)
  48. }
  49. else
  50. {
  51. boost::system::error_code ec(errno,
  52. boost::asio::error::get_system_category());
  53. boost::asio::detail::throw_error(ec, "pipe_select_interrupter");
  54. }
  55. }
  56. pipe_select_interrupter::~pipe_select_interrupter()
  57. {
  58. close_descriptors();
  59. }
  60. void pipe_select_interrupter::close_descriptors()
  61. {
  62. if (read_descriptor_ != -1)
  63. ::close(read_descriptor_);
  64. if (write_descriptor_ != -1)
  65. ::close(write_descriptor_);
  66. }
  67. void pipe_select_interrupter::recreate()
  68. {
  69. close_descriptors();
  70. write_descriptor_ = -1;
  71. read_descriptor_ = -1;
  72. open_descriptors();
  73. }
  74. void pipe_select_interrupter::interrupt()
  75. {
  76. char byte = 0;
  77. int result = ::write(write_descriptor_, &byte, 1);
  78. (void)result;
  79. }
  80. bool pipe_select_interrupter::reset()
  81. {
  82. for (;;)
  83. {
  84. char data[1024];
  85. int bytes_read = ::read(read_descriptor_, data, sizeof(data));
  86. if (bytes_read < 0 && errno == EINTR)
  87. continue;
  88. bool was_interrupted = (bytes_read > 0);
  89. while (bytes_read == sizeof(data))
  90. bytes_read = ::read(read_descriptor_, data, sizeof(data));
  91. return was_interrupted;
  92. }
  93. }
  94. } // namespace detail
  95. } // namespace asio
  96. } // namespace boost
  97. #include <boost/asio/detail/pop_options.hpp>
  98. #endif // !defined(BOOST_ASIO_HAS_EVENTFD)
  99. #endif // !defined(__SYMBIAN32__)
  100. #endif // !defined(__CYGWIN__)
  101. #endif // !defined(BOOST_WINDOWS)
  102. #endif // BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP