| 2091 | |
| 2092 | |
| 2093 | inline std::pair<OutBuffer, ErrBuffer> |
| 2094 | Communication::communicate_threaded(const char* msg, size_t length) |
| 2095 | { |
| 2096 | OutBuffer obuf; |
| 2097 | ErrBuffer ebuf; |
| 2098 | std::future<int> out_fut, err_fut; |
| 2099 | const int length_conv = length; |
| 2100 | |
| 2101 | if (stream_->output()) { |
| 2102 | obuf.add_cap(out_buf_cap_); |
| 2103 | |
| 2104 | out_fut = std::async(std::launch::async, |
| 2105 | [&obuf, this] { |
| 2106 | return util::read_all(this->stream_->output(), obuf.buf); |
| 2107 | }); |
| 2108 | } |
| 2109 | if (stream_->error()) { |
| 2110 | ebuf.add_cap(err_buf_cap_); |
| 2111 | |
| 2112 | err_fut = std::async(std::launch::async, |
| 2113 | [&ebuf, this] { |
| 2114 | return util::read_all(this->stream_->error(), ebuf.buf); |
| 2115 | }); |
| 2116 | } |
| 2117 | if (stream_->input()) { |
| 2118 | if (msg) { |
| 2119 | int wbytes = std::fwrite(msg, sizeof(char), length, stream_->input()); |
| 2120 | if (wbytes < length_conv) { |
| 2121 | if (errno != EPIPE && errno != EINVAL) { |
| 2122 | throw OSError("fwrite error", errno); |
| 2123 | } |
| 2124 | } |
| 2125 | } |
| 2126 | stream_->input_.reset(); |
| 2127 | } |
| 2128 | |
| 2129 | if (out_fut.valid()) { |
| 2130 | int res = out_fut.get(); |
| 2131 | if (res != -1) obuf.length = res; |
| 2132 | else obuf.length = 0; |
| 2133 | } |
| 2134 | if (err_fut.valid()) { |
| 2135 | int res = err_fut.get(); |
| 2136 | if (res != -1) ebuf.length = res; |
| 2137 | else ebuf.length = 0; |
| 2138 | } |
| 2139 | |
| 2140 | return std::make_pair(std::move(obuf), std::move(ebuf)); |
| 2141 | } |
| 2142 | |
| 2143 | } // end namespace detail |
| 2144 | |