diff --git a/cpp/src/arrow/filesystem/s3fs.cc b/cpp/src/arrow/filesystem/s3fs.cc index 43666f32b3da6..dd8b02af80645 100644 --- a/cpp/src/arrow/filesystem/s3fs.cc +++ b/cpp/src/arrow/filesystem/s3fs.cc @@ -1569,6 +1569,10 @@ class ObjectOutputStream final : public io::OutputStream { io::internal::CloseFromDestructor(this); } + std::shared_ptr Self() { + return std::dynamic_pointer_cast(shared_from_this()); + } + Status Init() { ARROW_ASSIGN_OR_RAISE(auto client_lock, holder_->Lock()); @@ -1687,9 +1691,9 @@ class ObjectOutputStream final : public io::OutputStream { RETURN_NOT_OK(EnsureReadyToFlushFromClose()); - auto self = std::dynamic_pointer_cast(shared_from_this()); // Wait for in-progress uploads to finish (if async writes are enabled) - return FlushAsync().Then([self]() { return self->FinishPartUploadAfterFlush(); }); + return FlushAsync().Then( + [self = Self()]() { return self->FinishPartUploadAfterFlush(); }); } bool closed() const override { return closed_; } @@ -1855,6 +1859,9 @@ class ObjectOutputStream final : public io::OutputStream { } // Notify completion if (--state->parts_in_progress == 0) { + // GH-41862: avoid potential deadlock if the Future's callback is called + // with the mutex taken. + lock.unlock(); state->pending_parts_completed.MarkFinished(state->status); } }