| 1940 | |
| 1941 | template <typename RequestType, typename OutcomeType> |
| 1942 | Status Upload( |
| 1943 | RequestType&& req, |
| 1944 | UploadResultCallbackFunction<RequestType, OutcomeType> sync_result_callback, |
| 1945 | UploadResultCallbackFunction<RequestType, OutcomeType> async_result_callback, |
| 1946 | const void* data, int64_t nbytes, std::shared_ptr<Buffer> owned_buffer = nullptr) { |
| 1947 | req.SetBucket(ToAwsString(path_.bucket)); |
| 1948 | req.SetKey(ToAwsString(path_.key)); |
| 1949 | req.SetContentLength(nbytes); |
| 1950 | RETURN_NOT_OK(SetSSECustomerKey(&req, sse_customer_key_)); |
| 1951 | |
| 1952 | if (!background_writes_) { |
| 1953 | // GH-45304: avoid setting a body stream if length is 0. |
| 1954 | // This workaround can be removed once we require AWS SDK 1.11.489 or later. |
| 1955 | if (nbytes != 0) { |
| 1956 | req.SetBody(std::make_shared<StringViewStream>(data, nbytes)); |
| 1957 | } |
| 1958 | |
| 1959 | ARROW_ASSIGN_OR_RAISE(auto outcome, TriggerUploadRequest(req, holder_)); |
| 1960 | |
| 1961 | RETURN_NOT_OK(sync_result_callback(req, upload_state_, part_number_, outcome)); |
| 1962 | } else { |
| 1963 | // (GH-45304: avoid setting a body stream if length is 0, see above) |
| 1964 | if (nbytes != 0) { |
| 1965 | // If the data isn't owned, make an immutable copy for the lifetime of the closure |
| 1966 | if (owned_buffer == nullptr) { |
| 1967 | ARROW_ASSIGN_OR_RAISE(owned_buffer, AllocateBuffer(nbytes, io_context_.pool())); |
| 1968 | memcpy(owned_buffer->mutable_data(), data, nbytes); |
| 1969 | } else { |
| 1970 | DCHECK_EQ(data, owned_buffer->data()); |
| 1971 | DCHECK_EQ(nbytes, owned_buffer->size()); |
| 1972 | } |
| 1973 | req.SetBody(std::make_shared<StringViewStream>(owned_buffer->data(), |
| 1974 | owned_buffer->size())); |
| 1975 | } |
| 1976 | |
| 1977 | { |
| 1978 | std::unique_lock<std::mutex> lock(upload_state_->mutex); |
| 1979 | if (upload_state_->uploads_in_progress++ == 0) { |
| 1980 | upload_state_->pending_uploads_completed = Future<>::Make(); |
| 1981 | } |
| 1982 | } |
| 1983 | |
| 1984 | // The closure keeps the buffer and the upload state alive |
| 1985 | auto deferred = [owned_buffer, holder = holder_, req = std::move(req), |
| 1986 | state = upload_state_, async_result_callback, |
| 1987 | part_number = part_number_]() mutable -> Status { |
| 1988 | ARROW_ASSIGN_OR_RAISE(auto outcome, TriggerUploadRequest(req, holder)); |
| 1989 | |
| 1990 | return async_result_callback(req, state, part_number, outcome); |
| 1991 | }; |
| 1992 | RETURN_NOT_OK(SubmitIO(io_context_, std::move(deferred))); |
| 1993 | } |
| 1994 | |
| 1995 | ++part_number_; |
| 1996 | |
| 1997 | return Status::OK(); |
| 1998 | } |
| 1999 |
nothing calls this directly
no test coverage detected