• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SRC_CORE_LIB_PROMISE_RACE_H
16 #define GRPC_SRC_CORE_LIB_PROMISE_RACE_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <utility>
21 
22 namespace grpc_core {
23 
24 namespace promise_detail {
25 
26 // Implementation type for Race combinator.
27 template <typename... Promises>
28 class Race;
29 
30 template <typename Promise, typename... Promises>
31 class Race<Promise, Promises...> {
32  public:
33   using Result = decltype(std::declval<Promise>()());
34 
Race(Promise promise,Promises...promises)35   GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION explicit Race(Promise promise,
36                                                      Promises... promises)
37       : promise_(std::move(promise)), next_(std::move(promises)...) {}
38 
operator()39   GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Result operator()() {
40     // Check our own promise.
41     auto r = promise_();
42     if (r.pending()) {
43       // Check the rest of them.
44       return next_();
45     }
46     // Return the first ready result.
47     return std::move(r.value());
48   }
49 
50  private:
51   // The Promise checked by this instance.
52   Promise promise_;
53   // We recursively expand to check the rest of the instances.
54   Race<Promises...> next_;
55 };
56 
57 template <typename Promise>
58 class Race<Promise> {
59  public:
60   using Result = decltype(std::declval<Promise>()());
Race(Promise promise)61   GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION explicit Race(Promise promise)
62       : promise_(std::move(promise)) {}
operator()63   GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Result operator()() {
64     return promise_();
65   }
66 
67  private:
68   Promise promise_;
69 };
70 
71 }  // namespace promise_detail
72 
73 /// Run all the promises, return the first result that's available.
74 /// If two results are simultaneously available, bias towards the first result
75 /// listed.
76 template <typename... Promises>
77 GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline promise_detail::Race<Promises...>
Race(Promises...promises)78 Race(Promises... promises) {
79   return promise_detail::Race<Promises...>(std::move(promises)...);
80 }
81 
82 }  // namespace grpc_core
83 
84 #endif  // GRPC_SRC_CORE_LIB_PROMISE_RACE_H
85