libmoost
|
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