xref: /aosp_15_r20/external/grpc-grpc/src/core/lib/promise/wait_for_callback.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2023 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_WAIT_FOR_CALLBACK_H
16 #define GRPC_SRC_CORE_LIB_PROMISE_WAIT_FOR_CALLBACK_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <memory>
21 #include <utility>
22 
23 #include "absl/base/thread_annotations.h"
24 
25 #include "src/core/lib/gprpp/sync.h"
26 #include "src/core/lib/promise/activity.h"
27 #include "src/core/lib/promise/poll.h"
28 
29 namespace grpc_core {
30 
31 // Bridge callback interfaces and promise interfaces.
32 // This class helps bridge older callback interfaces with promises:
33 // MakeWaitPromise() returns a promise that will wait until a callback created
34 // by MakeCallback() has been invoked.
35 class WaitForCallback {
36  public:
37   // Creates a promise that blocks until the callback is invoked.
MakeWaitPromise()38   auto MakeWaitPromise() {
39     return [state = state_]() -> Poll<Empty> {
40       MutexLock lock(&state->mutex);
41       if (state->done) return Empty{};
42       state->waker = GetContext<Activity>()->MakeNonOwningWaker();
43       return Pending{};
44     };
45   }
46 
47   // Creates a callback that unblocks the promise.
MakeCallback()48   auto MakeCallback() {
49     return [state = state_]() {
50       ReleasableMutexLock lock(&state->mutex);
51       state->done = true;
52       auto waker = std::move(state->waker);
53       lock.Release();
54       waker.Wakeup();
55     };
56   }
57 
58  private:
59   struct State {
60     Mutex mutex;
61     bool done ABSL_GUARDED_BY(mutex) = false;
62     Waker waker ABSL_GUARDED_BY(mutex);
63   };
64   const std::shared_ptr<State> state_{std::make_shared<State>()};
65 };
66 
67 }  // namespace grpc_core
68 
69 #endif  // GRPC_SRC_CORE_LIB_PROMISE_WAIT_FOR_CALLBACK_H
70