loop.h
Go to the documentation of this file.
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_CORE_LIB_PROMISE_LOOP_H
16 #define GRPC_CORE_LIB_PROMISE_LOOP_H
17 
19 
20 #include <new>
21 #include <type_traits>
22 #include <utility>
23 
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26 #include "absl/types/variant.h"
27 
30 
31 namespace grpc_core {
32 
33 // Special type - signals to loop to take another iteration, instead of
34 // finishing
35 struct Continue {};
36 
37 // Result of polling a loop promise - either Continue looping, or return a value
38 // T
39 template <typename T>
41 
42 namespace promise_detail {
43 
44 template <typename T>
45 struct LoopTraits;
46 
47 template <typename T>
48 struct LoopTraits<LoopCtl<T>> {
49  using Result = T;
51 };
52 
53 template <typename T>
54 struct LoopTraits<absl::StatusOr<LoopCtl<T>>> {
57  if (!value.ok()) return value.status();
58  const auto& inner = *value;
59  if (absl::holds_alternative<Continue>(inner)) return Continue{};
60  return absl::get<T>(inner);
61  }
62 };
63 
64 template <>
65 struct LoopTraits<absl::StatusOr<LoopCtl<absl::Status>>> {
69  if (!value.ok()) return value.status();
70  const auto& inner = *value;
71  if (absl::holds_alternative<Continue>(inner)) return Continue{};
72  return absl::get<absl::Status>(inner);
73  }
74 };
75 
76 template <typename F>
77 class Loop {
78  private:
80  using PromiseType = decltype(std::declval<Factory>().Repeated());
82 
83  public:
85 
86  explicit Loop(F f) : factory_(std::move(f)), promise_(factory_.Repeated()) {}
87  ~Loop() { promise_.~PromiseType(); }
88 
89  Loop(Loop&& loop) noexcept
90  : factory_(std::move(loop.factory_)),
91  promise_(std::move(loop.promise_)) {}
92 
93  Loop(const Loop& loop) = delete;
94  Loop& operator=(const Loop& loop) = delete;
95 
97  while (true) {
98  // Poll the inner promise.
99  auto promise_result = promise_();
100  // If it returns a value:
101  if (auto* p = absl::get_if<kPollReadyIdx>(&promise_result)) {
102  // - then if it's Continue, destroy the promise and recreate a new one
103  // from our factory.
105  if (absl::holds_alternative<Continue>(lc)) {
106  promise_.~PromiseType();
108  continue;
109  }
110  // - otherwise there's our result... return it out.
111  return absl::get<Result>(lc);
112  } else {
113  // Otherwise the inner promise was pending, so we are pending.
114  return Pending();
115  }
116  }
117  }
118 
119  private:
122 };
123 
124 } // namespace promise_detail
125 
126 // Looping combinator.
127 // Expects F returns LoopCtl<T> - if it's Continue, then run the loop again -
128 // otherwise yield the returned value as the result of the loop.
129 template <typename F>
132 }
133 
134 } // namespace grpc_core
135 
136 #endif // GRPC_CORE_LIB_PROMISE_LOOP_H
async_greeter_server_with_graceful_shutdown.loop
loop
Definition: async_greeter_server_with_graceful_shutdown.py:59
grpc_core::Continue
Definition: loop.h:35
absl::StatusOr
ABSL_NAMESPACE_BEGIN class ABSL_MUST_USE_RESULT StatusOr
Definition: abseil-cpp/absl/status/internal/statusor_internal.h:29
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::promise_detail::Loop::promise_
GPR_NO_UNIQUE_ADDRESS PromiseType promise_
Definition: loop.h:121
grpc_core::promise_detail::Loop::~Loop
~Loop()
Definition: loop.h:87
grpc_core::promise_detail::LoopTraits< LoopCtl< T > >::Result
T Result
Definition: loop.h:49
T
#define T(upbtypeconst, upbtype, ctype, default_value)
grpc_core::promise_detail::Loop::Loop
Loop(Loop &&loop) noexcept
Definition: loop.h:89
grpc_core::promise_detail::LoopTraits< absl::StatusOr< LoopCtl< absl::Status > > >::ToLoopCtl
static LoopCtl< Result > ToLoopCtl(absl::StatusOr< LoopCtl< absl::Status >> value)
Definition: loop.h:67
promise_factory.h
grpc_core::Pending
Definition: poll.h:29
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
re2::Result
TestInstance::Result Result
Definition: bloaty/third_party/re2/re2/testing/tester.cc:96
grpc_core::promise_detail::Loop::operator=
Loop & operator=(const Loop &loop)=delete
grpc_core::promise_detail::LoopTraits< LoopCtl< T > >::ToLoopCtl
static LoopCtl< T > ToLoopCtl(LoopCtl< T > value)
Definition: loop.h:50
GPR_NO_UNIQUE_ADDRESS
#define GPR_NO_UNIQUE_ADDRESS
Definition: impl/codegen/port_platform.h:692
grpc_core::Loop
promise_detail::Loop< F > Loop(F f)
Definition: loop.h:130
value
const char * value
Definition: hpack_parser_table.cc:165
absl::Status
ABSL_NAMESPACE_BEGIN class ABSL_MUST_USE_RESULT Status
Definition: abseil-cpp/absl/status/internal/status_internal.h:36
grpc_core::promise_detail::Loop::PromiseResult
typename PromiseType::Result PromiseResult
Definition: loop.h:81
poll.h
absl::Status
Definition: third_party/abseil-cpp/absl/status/status.h:424
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc_core::promise_detail::Loop::operator()
Poll< Result > operator()()
Definition: loop.h:96
grpc_core::promise_detail::LoopTraits
Definition: loop.h:45
grpc_core::promise_detail::Loop::factory_
GPR_NO_UNIQUE_ADDRESS Factory factory_
Definition: loop.h:120
grpc_core::promise_detail::PromiseFactory< void, F >
Definition: promise_factory.h:170
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
grpc_core::promise_detail::Loop::Loop
Loop(F f)
Definition: loop.h:86
absl::StatusOr
Definition: abseil-cpp/absl/status/statusor.h:187
grpc_core::promise_detail::LoopTraits< absl::StatusOr< LoopCtl< T > > >::ToLoopCtl
static LoopCtl< Result > ToLoopCtl(absl::StatusOr< LoopCtl< T >> value)
Definition: loop.h:56
grpc_core::promise_detail::PromiseFactory< void, F >::Repeated
Promise Repeated() const
Definition: promise_factory.h:182
absl::variant
Definition: abseil-cpp/absl/types/internal/variant.h:46
grpc_core::promise_detail::Loop::PromiseType
decltype(std::declval< Factory >().Repeated()) PromiseType
Definition: loop.h:80
grpc_core::promise_detail::Loop::Result
typename LoopTraits< PromiseResult >::Result Result
Definition: loop.h:84
port_platform.h
grpc_core::promise_detail::Loop
Definition: loop.h:77


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:30