| 1999 | |
| 2000 | template <typename RequestType, typename OutcomeType> |
| 2001 | Status Upload( |
| 2002 | RequestType&& req, |
| 2003 | UploadResultCallbackFunction<RequestType, OutcomeType> sync_result_callback, |
| 2004 | UploadResultCallbackFunction<RequestType, OutcomeType> async_result_callback, |
| 2005 | const void* data, int64_t nbytes, std::shared_ptr<Buffer> owned_buffer = nullptr) { |
| 2006 | req.SetBucket(ToAwsString(path_.bucket)); |
| 2007 | req.SetKey(ToAwsString(path_.key)); |
| 2008 | req.SetContentLength(nbytes); |
| 2009 | RETURN_NOT_OK(SetSSECustomerKey(&req, sse_customer_key_)); |
| 2010 | |
| 2011 | if (!background_writes_) { |
| 2012 | // GH-45304: avoid setting a body stream if length is 0. |
| 2013 | // This workaround can be removed once we require AWS SDK 1.11.489 or later. |
| 2014 | if (nbytes != 0) { |
| 2015 | req.SetBody(std::make_shared<StringViewStream>(data, nbytes)); |
| 2016 | } |
| 2017 | |
| 2018 | ARROW_ASSIGN_OR_RAISE(auto outcome, TriggerUploadRequest(req, holder_)); |
| 2019 | |
| 2020 | RETURN_NOT_OK(sync_result_callback(req, upload_state_, part_number_, outcome)); |
| 2021 | } else { |
| 2022 | // (GH-45304: avoid setting a body stream if length is 0, see above) |
| 2023 | if (nbytes != 0) { |
| 2024 | // If the data isn't owned, make an immutable copy for the lifetime of the closure |
| 2025 | if (owned_buffer == nullptr) { |
| 2026 | ARROW_ASSIGN_OR_RAISE(owned_buffer, AllocateBuffer(nbytes, io_context_.pool())); |
| 2027 | memcpy(owned_buffer->mutable_data(), data, nbytes); |
| 2028 | } else { |
| 2029 | DCHECK_EQ(data, owned_buffer->data()); |
| 2030 | DCHECK_EQ(nbytes, owned_buffer->size()); |
| 2031 | } |
| 2032 | req.SetBody(std::make_shared<StringViewStream>(owned_buffer->data(), |
| 2033 | owned_buffer->size())); |
| 2034 | } |
| 2035 | |
| 2036 | { |
| 2037 | std::unique_lock<std::mutex> lock(upload_state_->mutex); |
| 2038 | if (upload_state_->uploads_in_progress++ == 0) { |
| 2039 | upload_state_->pending_uploads_completed = Future<>::Make(); |
| 2040 | } |
| 2041 | } |
| 2042 | |
| 2043 | // The closure keeps the buffer and the upload state alive |
| 2044 | auto deferred = [owned_buffer, holder = holder_, req = std::move(req), |
| 2045 | state = upload_state_, async_result_callback, |
| 2046 | part_number = part_number_]() mutable -> Status { |
| 2047 | ARROW_ASSIGN_OR_RAISE(auto outcome, TriggerUploadRequest(req, holder)); |
| 2048 | |
| 2049 | return async_result_callback(req, state, part_number, outcome); |
| 2050 | }; |
| 2051 | RETURN_NOT_OK(SubmitIO(io_context_, std::move(deferred))); |
| 2052 | } |
| 2053 | |
| 2054 | ++part_number_; |
| 2055 | |
| 2056 | return Status::OK(); |
| 2057 | } |
| 2058 |
nothing calls this directly
no test coverage detected