| 826 | } |
| 827 | |
| 828 | void DiskQueue::DiskThreadLoop(DiskIoMgr* io_mgr) { |
| 829 | // The thread waits until there is work or the queue is shut down. If there is work, |
| 830 | // performs the read or write requested. Locks are not taken when reading from or |
| 831 | // writing to disk. |
| 832 | while (true) { |
| 833 | RequestContext* worker_context = nullptr; |
| 834 | RequestRange* range = GetNextRequestRange(&worker_context); |
| 835 | if (range == nullptr) { |
| 836 | DCHECK(shut_down_); |
| 837 | return; |
| 838 | } |
| 839 | // We are now working on behalf of a query, so set thread state appropriately. |
| 840 | // See also IMPALA-6254 and IMPALA-6417. |
| 841 | ScopedThreadContext tdi_scope(GetThreadDebugInfo(), worker_context->query_id(), |
| 842 | worker_context->instance_id()); |
| 843 | |
| 844 | switch (range->request_type()) { |
| 845 | case RequestType::READ: { |
| 846 | ScanRange* scan_range = static_cast<ScanRange*>(range); |
| 847 | ReadOutcome outcome = scan_range->DoRead(this, disk_id_); |
| 848 | worker_context->ReadDone(disk_id_, outcome, scan_range); |
| 849 | break; |
| 850 | } |
| 851 | case RequestType::WRITE: { |
| 852 | WriteRange* write_range = static_cast<WriteRange*>(range); |
| 853 | Status status = write_range->DoWrite(); |
| 854 | worker_context->OperDone(write_range, status); |
| 855 | break; |
| 856 | } |
| 857 | case RequestType::FILE_UPLOAD: { |
| 858 | RemoteOperRange* oper_range = static_cast<RemoteOperRange*>(range); |
| 859 | int64_t size = oper_range->block_size(); |
| 860 | // Use malloc to get the memory in case there is no available space |
| 861 | // in the buffer pool because spilling to disk happens when scarcity |
| 862 | // of memory in the buffer pool. Be better to preserve memory than |
| 863 | // malloc. |
| 864 | uint8_t* buffer = static_cast<uint8_t*>(malloc(size)); |
| 865 | if (UNLIKELY(buffer == nullptr)) { |
| 866 | worker_context->OperDone(oper_range, |
| 867 | Status(Substitute("Couldn't allocate memory for remote file operations, " |
| 868 | "block size: '$0'", |
| 869 | size))); |
| 870 | } else { |
| 871 | Status oper_status = oper_range->DoUpload(buffer, size); |
| 872 | worker_context->OperDone(oper_range, oper_status); |
| 873 | free(buffer); |
| 874 | } |
| 875 | break; |
| 876 | } |
| 877 | case RequestType::FILE_FETCH: { |
| 878 | RemoteOperRange* oper_range = static_cast<RemoteOperRange*>(range); |
| 879 | Status oper_status = oper_range->DoFetch(); |
| 880 | worker_context->OperDone(oper_range, oper_status); |
| 881 | break; |
| 882 | } |
| 883 | default: |
| 884 | DCHECK(false) << "Invalid request type: " << range->request_type(); |
| 885 | } |
nothing calls this directly
no test coverage detected