| 181 | } |
| 182 | |
| 183 | void RemoteQueryExecutorReadContext::cancel() |
| 184 | { |
| 185 | std::lock_guard guard(fiber_lock); |
| 186 | |
| 187 | /// It is safe to just destroy fiber - we are not in the process of reading from socket. |
| 188 | boost::context::fiber to_destroy = std::move(fiber); |
| 189 | |
| 190 | /// One should not try to wait for the current packet here in case of |
| 191 | /// timeout because this will exceed the timeout. |
| 192 | /// Anyway if the timeout is exceeded, then the connection will be shutdown |
| 193 | /// (disconnected), so it will not left in an unsynchronised state. |
| 194 | if (!is_timer_alarmed) |
| 195 | { |
| 196 | /// Wait for current pending packet, to avoid leaving connection in unsynchronised state. |
| 197 | while (is_read_in_progress.load(std::memory_order_relaxed)) |
| 198 | { |
| 199 | checkTimeout(/* blocking= */ true); |
| 200 | to_destroy = std::move(to_destroy).resume(); |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | /// Send something to pipe to cancel executor waiting. |
| 205 | uint64_t buf = 0; |
| 206 | while (-1 == write(pipe_fd[1], &buf, sizeof(buf))) |
| 207 | { |
| 208 | if (errno == EAGAIN) |
| 209 | break; |
| 210 | |
| 211 | if (errno != EINTR) |
| 212 | throwFromErrno("Cannot write to pipe", ErrorCodes::CANNOT_READ_FROM_SOCKET); |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | RemoteQueryExecutorReadContext::~RemoteQueryExecutorReadContext() |
| 217 | { |
nothing calls this directly
no test coverage detected