libmoost
/home/mhx/git/github/libmoost/include/moost/io/detail/async_stream_forwarder_posix.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef MOOST_IO_DETAIL_ASYNC_STREAM_FORWARDER_POSIX_HPP__
00029 #define MOOST_IO_DETAIL_ASYNC_STREAM_FORWARDER_POSIX_HPP__
00030 
00031 #include <unistd.h>
00032 #include <poll.h>
00033 
00034 namespace moost { namespace io { namespace detail {
00035 
00036 class forwarding_loop
00037 {
00038 public:
00039    forwarding_loop()
00040      : m_signal_in(-1)
00041    {
00042    }
00043 
00044    void stop() const
00045    {
00046       if (m_signal_in != -1)
00047       {
00048          char input = 'S';
00049          if (::write(m_signal_in, &input, 1) != 1)
00050          {
00051             // there's just nothing we can do...
00052          }
00053       }
00054    }
00055 
00056    void run(int from, int to) const
00057    {
00058       int signal_out;
00059       moost::io::helper::create_pipe(signal_out, m_signal_in);
00060 
00061       char input;
00062       struct pollfd pfd[2];
00063       pfd[0].fd = from;
00064       pfd[0].events = POLLIN;
00065       pfd[1].fd = signal_out;
00066       pfd[1].events = POLLIN;
00067 
00068       for (;;)
00069       {
00070          pfd[0].revents = 0;
00071          pfd[1].revents = 0;
00072 
00073          int rv = ::poll(&pfd[0], 2, -1);
00074 
00075          if (rv <= 0)
00076          {
00077             break;
00078          }
00079 
00080          if (pfd[1].revents & POLLIN)
00081          {
00082             break;
00083          }
00084          else if (pfd[0].revents & POLLIN)
00085          {
00086             if (::read(from, &input, 1) != 1 ||
00087                 ::write(to, &input, 1) != 1)
00088             {
00089                break;
00090             }
00091          }
00092       }
00093    }
00094 
00095 private:
00096    mutable int m_signal_in;
00097 };
00098 
00099 } } }
00100 
00101 #endif