MCPcopy Create free account
hub / github.com/apache/arrow / Loop

Function Loop

cpp/src/arrow/util/future.h:808–856  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

806 typename Control = typename detail::result_of_t<Iterate()>::ValueType,
807 typename BreakValueType = typename Control::value_type>
808Future<BreakValueType> Loop(Iterate iterate) {
809 struct Callback {
810 bool CheckForTermination(const Result<Control>& control_res) {
811 if (!control_res.ok()) {
812 break_fut.MarkFinished(control_res.status());
813 return true;
814 }
815 if (control_res->has_value()) {
816 break_fut.MarkFinished(**control_res);
817 return true;
818 }
819 return false;
820 }
821
822 void operator()(const Result<Control>& maybe_control) && {
823 if (CheckForTermination(maybe_control)) return;
824
825 auto control_fut = iterate();
826 while (true) {
827 if (control_fut.TryAddCallback([this]() { return *this; })) {
828 // Adding a callback succeeded; control_fut was not finished
829 // and we must wait to CheckForTermination.
830 return;
831 }
832 // Adding a callback failed; control_fut was finished and we
833 // can CheckForTermination immediately. This also avoids recursion and potential
834 // stack overflow.
835 if (CheckForTermination(control_fut.result())) return;
836
837 control_fut = iterate();
838 }
839 }
840
841 Iterate iterate;
842
843 // If the future returned by control_fut is never completed then we will be hanging on
844 // to break_fut forever even if the listener has given up listening on it. Instead we
845 // rely on the fact that a producer (the caller of Future<>::Make) is always
846 // responsible for completing the futures they create.
847 // TODO: Could avoid this kind of situation with "future abandonment" similar to mesos
848 Future<BreakValueType> break_fut;
849 };
850
851 auto break_fut = Future<BreakValueType>::Make();
852 auto control_fut = iterate();
853 control_fut.AddCallback(Callback{std::move(iterate), break_fut});
854
855 return break_fut;
856}
857
858inline Future<> ToFuture(Status status) {
859 return Future<>::MakeFinished(std::move(status));

Callers 5

ARROW_ASSIGN_OR_RAISEMethod · 0.85
FirstBlockMethod · 0.85
VisitAsyncGeneratorFunction · 0.85
CollectAsyncGeneratorFunction · 0.85
TESTFunction · 0.85

Calls 2

MakeFunction · 0.70
AddCallbackMethod · 0.45

Tested by 1

TESTFunction · 0.68