| 395 | } |
| 396 | |
| 397 | void ScanRange::CancelInternal(const Status& status, bool read_error) { |
| 398 | DCHECK(io_mgr_ != nullptr); |
| 399 | DCHECK(!status.ok()); |
| 400 | FileReader* file_reader = nullptr; |
| 401 | { |
| 402 | // Grab both locks to make sure that we don't change 'cancel_status_' while other |
| 403 | // threads are in critical sections. |
| 404 | unique_lock<mutex> scan_range_lock(lock_); |
| 405 | { |
| 406 | file_reader = use_local_buffer_ ? local_buffer_reader_.get() : file_reader_.get(); |
| 407 | unique_lock<SpinLock> fs_lock(file_reader->lock()); |
| 408 | DCHECK(Validate(scan_range_lock)) << DebugString(); |
| 409 | // If already cancelled, preserve the original reason for cancellation. Most of the |
| 410 | // cleanup is not required if already cancelled, but we need to set |
| 411 | // 'read_in_flight_' to false. |
| 412 | if (cancel_status_.ok()) cancel_status_ = status; |
| 413 | } |
| 414 | |
| 415 | /// Clean up ready buffers (i.e., 'buffer_manager_->ready_buffers_') while still |
| 416 | /// holding 'lock_' to prevent other threads from seeing inconsistent state. |
| 417 | buffer_manager_->CleanUpReadyBuffers(scan_range_lock); |
| 418 | |
| 419 | /// Clean up buffers that we don't need any more because we won't read any more data. |
| 420 | buffer_manager_->CleanUpUnusedBuffers(scan_range_lock); |
| 421 | if (read_error) { |
| 422 | DCHECK(read_in_flight_); |
| 423 | read_in_flight_ = false; |
| 424 | } |
| 425 | } |
| 426 | buffer_ready_cv_.NotifyAll(); |
| 427 | |
| 428 | // For cached buffers, we can't close the range until the cached buffer is returned. |
| 429 | // Close() is called from ScanRange::CleanUpBufferLocked(). |
| 430 | // TODO: IMPALA-4249 - this Close() call makes it unsafe to reuse a cancelled scan |
| 431 | // range, because there is no synchronisation between this Close() call and the |
| 432 | // client adding the ScanRange back into the IoMgr. |
| 433 | if (!buffer_manager_->is_cached()) { |
| 434 | DCHECK(file_reader != nullptr); |
| 435 | file_reader->Close(); |
| 436 | } |
| 437 | } |
| 438 | |
| 439 | void ScanRange::WaitForInFlightRead() { |
| 440 | unique_lock<mutex> scan_range_lock(lock_); |
no test coverage detected