| 170 | } |
| 171 | |
| 172 | int FiberStreamSocketImpl::receiveBytes(void * buffer, int length, int flags) |
| 173 | { |
| 174 | if (flags != 0) |
| 175 | throw DB::Exception( |
| 176 | DB::ErrorCodes::LOGICAL_ERROR, |
| 177 | "Silk::FiberStreamSocketImpl::receiveBytes: non-zero flags ({}) not supported", |
| 178 | flags); |
| 179 | |
| 180 | throttleRecv(static_cast<size_t>(length), getBlocking()); |
| 181 | |
| 182 | uint64_t bytes_read = 0; |
| 183 | silk::FiberScheduler::IoFuture future; |
| 184 | iovec iov{buffer, static_cast<size_t>(length)}; |
| 185 | silk::FiberScheduler::read(sockfd(), &iov, 1, 0, &bytes_read, &future); |
| 186 | |
| 187 | Poco::Timespan timeout = getReceiveTimeout(); |
| 188 | int r = 0; |
| 189 | if (timeout.totalMicroseconds() > 0) |
| 190 | { |
| 191 | r = silk::FiberFuture::waitWithTimeout( |
| 192 | &future, |
| 193 | static_cast<uint64_t>(timeout.totalMicroseconds()) * 1000); |
| 194 | if (r == ETIMEDOUT) |
| 195 | { |
| 196 | future.cancel(); |
| 197 | r = future.wait(); |
| 198 | if (r == ECANCELED) |
| 199 | throw Poco::TimeoutException("Receive timed out", peerAddress().toString()); |
| 200 | } |
| 201 | } |
| 202 | else |
| 203 | { |
| 204 | r = future.wait(); |
| 205 | } |
| 206 | |
| 207 | if (r) |
| 208 | error(r, "recv"); |
| 209 | |
| 210 | useRecvThrottlerBudget(static_cast<int>(bytes_read)); |
| 211 | |
| 212 | return static_cast<int>(bytes_read); |
| 213 | } |
| 214 | |
| 215 | void FiberStreamSocketImpl::setBlocking(bool flag) |
| 216 | { |