pitrou commented on a change in pull request #9528: URL: https://github.com/apache/arrow/pull/9528#discussion_r578685677
########## File path: cpp/src/arrow/util/future.h ########## @@ -515,15 +548,35 @@ class ARROW_MUST_USE_TYPE Future { } void DoMarkFinished(Result<ValueType> res) { - SetResult(std::move(res)); - - if (ARROW_PREDICT_TRUE(GetResult()->ok())) { - impl_->MarkFinished(); + const FutureState state = StateForResult(res); + if (impl_->stop_callback_.has_value()) { + struct ResultSetter { + Future<T>* fut; + Result<ValueType> res; + + void operator()() { fut->SetResult(std::move(res)); } + }; + impl_->MarkFinished(state, ResultSetter{this, std::move(res)}); } else { - impl_->MarkFailed(); + // The future cannot be cancelled concurrently as CancelOn() + // was not called. + SetResult(std::move(res)); + impl_->MarkFinished(state); } Review comment: Unfortunately, having the ability to cancel from one thread while marking a future finished from another thread introduces some execution costs inside the Future class. Here, we see that if some cancellation may occur, we must synchronize result writing inside `FutureImpl::MarkFinished`. cc @westonpace ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org