activity.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_ACTIVITY_H
16 #define GRPC_CORE_LIB_PROMISE_ACTIVITY_H
17 
19 
20 #include <stdint.h>
21 
22 #include <algorithm>
23 #include <atomic>
24 #include <memory>
25 #include <utility>
26 
27 #include "absl/base/thread_annotations.h"
28 #include "absl/status/status.h"
29 #include "absl/types/optional.h"
30 #include "absl/types/variant.h"
31 #include "absl/utility/utility.h"
32 
33 #include <grpc/support/log.h>
34 
35 #include "src/core/lib/gpr/tls.h"
43 
44 namespace grpc_core {
45 
46 // A Wakeable object is used by queues to wake activities.
47 class Wakeable {
48  public:
49  // Wake up the underlying activity.
50  // After calling, this Wakeable cannot be used again.
51  virtual void Wakeup() = 0;
52  // Drop this wakeable without waking up the underlying activity.
53  virtual void Drop() = 0;
54 
55  protected:
56  inline ~Wakeable() {}
57 };
58 
59 // An owning reference to a Wakeable.
60 // This type is non-copyable but movable.
61 class Waker {
62  public:
63  explicit Waker(Wakeable* wakeable) : wakeable_(wakeable) {}
64  Waker() : Waker(nullptr) {}
65  ~Waker() {
66  if (wakeable_ != nullptr) wakeable_->Drop();
67  }
68  Waker(const Waker&) = delete;
69  Waker& operator=(const Waker&) = delete;
70  Waker(Waker&& other) noexcept : wakeable_(other.Take()) {}
71  Waker& operator=(Waker&& other) noexcept {
72  std::swap(wakeable_, other.wakeable_);
73  return *this;
74  }
75 
76  // Wake the underlying activity.
77  void Wakeup() {
78  if (auto* wakeable = Take()) wakeable->Wakeup();
79  }
80 
81  template <typename H>
82  friend H AbslHashValue(H h, const Waker& w) {
83  return H::combine(std::move(h), w.wakeable_);
84  }
85 
86  bool operator==(const Waker& other) const noexcept {
87  return wakeable_ == other.wakeable_;
88  }
89 
90  private:
91  Wakeable* Take() { return absl::exchange(wakeable_, nullptr); }
92 
94 };
95 
96 // An Activity tracks execution of a single promise.
97 // It executes the promise under a mutex.
98 // When the promise stalls, it registers the containing activity to be woken up
99 // later.
100 // The activity takes a callback, which will be called exactly once with the
101 // result of execution.
102 // Activity execution may be cancelled by simply deleting the activity. In such
103 // a case, if execution had not already finished, the done callback would be
104 // called with absl::CancelledError().
105 class Activity : public Orphanable {
106  public:
107  // Force wakeup from the outside.
108  // This should be rarely needed, and usages should be accompanied with a note
109  // on why it's not possible to wakeup with a Waker object.
110  // Nevertheless, it's sometimes useful for integrations with Activity to force
111  // an Activity to repoll.
113 
114  // Force the current activity to immediately repoll if it doesn't complete.
115  virtual void ForceImmediateRepoll() = 0;
116 
117  // Return the current activity.
118  // Additionally:
119  // - assert that there is a current activity (and catch bugs if there's not)
120  // - indicate to thread safety analysis that the current activity is indeed
121  // locked
122  // - back up that assertation with a runtime check in debug builds (it's
123  // prohibitively expensive in non-debug builds)
124  static Activity* current() { return g_current_activity_; }
125 
126  // Produce an activity-owning Waker. The produced waker will keep the activity
127  // alive until it's awoken or dropped.
128  virtual Waker MakeOwningWaker() = 0;
129 
130  // Produce a non-owning Waker. The waker will own a small heap allocated weak
131  // pointer to this activity. This is more suitable for wakeups that may not be
132  // delivered until long after the activity should be destroyed.
133  virtual Waker MakeNonOwningWaker() = 0;
134 
135  protected:
136  // Check if this activity is the current activity executing on the current
137  // thread.
138  bool is_current() const { return this == g_current_activity_; }
139  // Check if there is an activity executing on the current thread.
140  static bool have_current() { return g_current_activity_ != nullptr; }
141  // Set the current activity at construction, clean it up at destruction.
143  public:
144  explicit ScopedActivity(Activity* activity)
145  : prior_activity_(g_current_activity_) {
146  g_current_activity_ = activity;
147  }
148  ~ScopedActivity() { g_current_activity_ = prior_activity_; }
149  ScopedActivity(const ScopedActivity&) = delete;
150  ScopedActivity& operator=(const ScopedActivity&) = delete;
151 
152  private:
154  };
155 
156  private:
157  // Set during RunLoop to the Activity that's executing.
158  // Being set implies that mu_ is held.
159  static GPR_THREAD_LOCAL(Activity*) g_current_activity_;
160 };
161 
162 // Owned pointer to one Activity.
164 
165 namespace promise_detail {
166 
167 template <typename Context>
169  public:
171 
173  Context* GetContext() { return &value_; }
174 
175  private:
177 };
178 
179 template <typename Context>
181  public:
183 
185  Context* GetContext() { return value_; }
186 
187  private:
189 };
190 
191 template <typename Context, typename Deleter>
192 class ContextHolder<std::unique_ptr<Context, Deleter>> {
193  public:
195 
196  explicit ContextHolder(std::unique_ptr<Context, Deleter> value)
197  : value_(std::move(value)) {}
198  Context* GetContext() { return value_.get(); }
199 
200  private:
201  std::unique_ptr<Context, Deleter> value_;
202 };
203 
204 template <typename HeldContext>
206 
207 template <typename... Contexts>
208 class ActivityContexts : public ContextHolder<Contexts>... {
209  public:
210  explicit ActivityContexts(Contexts&&... contexts)
211  : ContextHolder<Contexts>(std::forward<Contexts>(contexts))... {}
212 
213  class ScopedContext : public Context<ContextTypeFromHeld<Contexts>>... {
214  public:
215  explicit ScopedContext(ActivityContexts* contexts)
216  : Context<ContextTypeFromHeld<Contexts>>(
217  static_cast<ContextHolder<Contexts>*>(contexts)
218  ->GetContext())... {}
219  };
220 };
221 
222 // A free standing activity: an activity that owns its own synchronization and
223 // memory.
224 // The alternative is an activity that's somehow tied into another system, for
225 // instance the type seen in promise_based_filter.h as we're transitioning from
226 // the old filter stack to the new system.
227 // FreestandingActivity is-a Wakeable, but needs to increment a refcount before
228 // returning that Wakeable interface. Additionally, we want to keep
229 // FreestandingActivity as small as is possible, since it will be used
230 // everywhere. So we use inheritance to provide the Wakeable interface: this
231 // makes it zero sized, and we make the inheritance private to prevent
232 // accidental casting.
233 class FreestandingActivity : public Activity, private Wakeable {
234  public:
236  Ref();
237  return Waker(this);
238  }
239  Waker MakeNonOwningWaker() final;
240 
241  void Orphan() final {
242  Cancel();
243  Unref();
244  }
245 
246  void ForceImmediateRepoll() final {
247  mu_.AssertHeld();
249  }
250 
251  protected:
252  // Action received during a run, in priority order.
253  // If more than one action is received during a run, we use max() to resolve
254  // which one to report (so Cancel overrides Wakeup).
255  enum class ActionDuringRun : uint8_t {
256  kNone, // No action occured during run.
257  kWakeup, // A wakeup occured during run.
258  kCancel, // Cancel was called during run.
259  };
260 
261  inline ~FreestandingActivity() override {
262  if (handle_) {
263  DropHandle();
264  }
265  }
266 
267  // Check if we got an internal wakeup since the last time this function was
268  // called.
270  return absl::exchange(action_during_run_, ActionDuringRun::kNone);
271  }
272 
273  // Implementors of Wakeable::Wakeup should call this after the wakeup has
274  // completed.
275  void WakeupComplete() { Unref(); }
276 
277  // Set the action that occured during this run.
278  // We use max to combine actions so that cancellation overrides wakeups.
281  action_during_run_ = std::max(action_during_run_, action);
282  }
283 
284  Mutex* mu() ABSL_LOCK_RETURNED(mu_) { return &mu_; }
285 
286  private:
287  class Handle;
288 
289  // Cancel execution of the underlying promise.
290  virtual void Cancel() = 0;
291 
292  void Ref() { refs_.fetch_add(1, std::memory_order_relaxed); }
293  void Unref() {
294  if (1 == refs_.fetch_sub(1, std::memory_order_acq_rel)) {
295  delete this;
296  }
297  }
298 
299  // Return a Handle instance with a ref so that it can be stored waiting for
300  // some wakeup.
302  // If our refcount is non-zero, ref and return true.
303  // Otherwise, return false.
304  bool RefIfNonzero();
305  // Drop the (proved existing) wait handle.
307 
308  // All promise execution occurs under this mutex.
310 
311  // Current refcount.
312  std::atomic<uint32_t> refs_{1};
313  // If wakeup is called during Promise polling, we set this to Wakeup and
314  // repoll. If cancel is called during Promise polling, we set this to Cancel
315  // and cancel at the end of polling.
316  ActionDuringRun action_during_run_ ABSL_GUARDED_BY(mu_) =
318  // Handle for long waits. Allows a very small weak pointer type object to
319  // queue for wakeups while Activity may be deleted earlier.
320  Handle* handle_ ABSL_GUARDED_BY(mu_) = nullptr;
321 };
322 
323 // Implementation details for an Activity of an arbitrary type of promise.
324 // There should exist a static function:
325 // struct WakeupScheduler {
326 // template <typename ActivityType>
327 // void ScheduleWakeup(ActivityType* activity);
328 // };
329 // This function should arrange that activity->RunScheduledWakeup() be invoked
330 // at the earliest opportunity.
331 // It can assume that activity will remain live until RunScheduledWakeup() is
332 // invoked, and that a given activity will not be concurrently scheduled again
333 // until its RunScheduledWakeup() has been invoked.
334 // We use private inheritance here as a way of getting private members for
335 // each of the contexts.
336 // TODO(ctiller): We can probably reconsider the private inheritance here
337 // when we move away from C++11 and have more powerful template features.
338 template <class F, class WakeupScheduler, class OnDone, typename... Contexts>
340  private ActivityContexts<Contexts...> {
341  public:
344 
345  PromiseActivity(F promise_factory, WakeupScheduler wakeup_scheduler,
346  OnDone on_done, Contexts&&... contexts)
348  ActivityContexts<Contexts...>(std::forward<Contexts>(contexts)...),
349  wakeup_scheduler_(std::move(wakeup_scheduler)),
350  on_done_(std::move(on_done)) {
351  // Lock, construct an initial promise from the factory, and step it.
352  // This may hit a waiter, which could expose our this pointer to other
353  // threads, meaning we do need to hold this mutex even though we're still
354  // constructing.
355  mu()->Lock();
356  auto status = Start(Factory(std::move(promise_factory)));
357  mu()->Unlock();
358  // We may complete immediately.
359  if (status.has_value()) {
361  }
362  }
363 
364  ~PromiseActivity() override {
365  // We shouldn't destruct without calling Cancel() first, and that must get
366  // us to be done_, so we assume that and have no logic to destruct the
367  // promise here.
368  GPR_ASSERT(done_);
369  }
370 
372  GPR_ASSERT(wakeup_scheduled_.exchange(false, std::memory_order_acq_rel));
373  Step();
374  WakeupComplete();
375  }
376 
377  private:
378  using typename ActivityContexts<Contexts...>::ScopedContext;
379 
380  void Cancel() final {
381  if (Activity::is_current()) {
382  mu()->AssertHeld();
384  return;
385  }
386  bool was_done;
387  {
388  MutexLock lock(mu());
389  // Check if we were done, and flag done.
390  was_done = done_;
391  if (!done_) MarkDone();
392  }
393  // If we were not done, then call the on_done callback.
394  if (!was_done) {
396  }
397  }
398 
399  // Wakeup this activity. Arrange to poll the activity again at a convenient
400  // time: this could be inline if it's deemed safe, or it could be by passing
401  // the activity to an external threadpool to run. If the activity is already
402  // running on this thread, a note is taken of such and the activity is
403  // repolled if it doesn't complete.
404  void Wakeup() final {
405  // If there is an active activity, but hey it's us, flag that and we'll loop
406  // in RunLoop (that's calling from above here!).
407  if (Activity::is_current()) {
408  mu()->AssertHeld();
410  WakeupComplete();
411  return;
412  }
413  if (!wakeup_scheduled_.exchange(true, std::memory_order_acq_rel)) {
414  // Can't safely run, so ask to run later.
415  wakeup_scheduler_.ScheduleWakeup(this);
416  } else {
417  // Already a wakeup scheduled for later, drop ref.
418  WakeupComplete();
419  }
420  }
421 
422  // Drop a wakeup
423  void Drop() final { this->WakeupComplete(); }
424 
425  // Notification that we're no longer executing - it's ok to destruct the
426  // promise.
428  GPR_ASSERT(!done_);
429  done_ = true;
430  Destruct(&promise_holder_.promise);
431  }
432 
433  // In response to Wakeup, run the Promise state machine again until it
434  // settles. Then check for completion, and if we have completed, call on_done.
436  // Poll the promise until things settle out under a lock.
437  mu()->Lock();
438  if (done_) {
439  // We might get some spurious wakeups after finishing.
440  mu()->Unlock();
441  return;
442  }
443  auto status = RunStep();
444  mu()->Unlock();
445  if (status.has_value()) {
447  }
448  }
449 
450  // The main body of a step: set the current activity, and any contexts, and
451  // then run the main polling loop. Contained in a function by itself in
452  // order to keep the scoping rules a little easier in Step().
454  ScopedActivity scoped_activity(this);
455  ScopedContext contexts(this);
456  return StepLoop();
457  }
458 
459  // Similarly to RunStep, but additionally construct the promise from a
460  // promise factory before entering the main loop. Called once from the
461  // constructor.
464  ScopedActivity scoped_activity(this);
465  ScopedContext contexts(this);
466  Construct(&promise_holder_.promise, promise_factory.Once());
467  return StepLoop();
468  }
469 
470  // Until there are no wakeups from within and the promise is incomplete:
471  // poll the promise.
474  while (true) {
475  // Run the promise.
476  GPR_ASSERT(!done_);
477  auto r = promise_holder_.promise();
478  if (auto* status = absl::get_if<kPollReadyIdx>(&r)) {
479  // If complete, destroy the promise, flag done, and exit this loop.
480  MarkDone();
481  return IntoStatus(status);
482  }
483  // Continue looping til no wakeups occur.
484  switch (GotActionDuringRun()) {
486  return {};
488  break;
490  MarkDone();
491  return absl::CancelledError();
492  }
493  }
494  }
495 
496  using Promise = typename Factory::Promise;
497  // Scheduler for wakeups
499  // Callback on completion of the promise.
501  // Has execution completed?
503  // Is there a wakeup scheduled?
504  GPR_NO_UNIQUE_ADDRESS std::atomic<bool> wakeup_scheduled_{false};
505  // We wrap the promise in a union to allow control over the construction
506  // simultaneously with annotating mutex requirements and noting that the
507  // promise contained may not use any memory.
512  };
514 };
515 
516 } // namespace promise_detail
517 
518 // Given a functor that returns a promise (a promise factory), a callback for
519 // completion, and a callback scheduler, construct an activity.
520 template <typename Factory, typename WakeupScheduler, typename OnDone,
521  typename... Contexts>
522 ActivityPtr MakeActivity(Factory promise_factory,
523  WakeupScheduler wakeup_scheduler, OnDone on_done,
524  Contexts&&... contexts) {
525  return ActivityPtr(
526  new promise_detail::PromiseActivity<Factory, WakeupScheduler, OnDone,
527  Contexts...>(
528  std::move(promise_factory), std::move(wakeup_scheduler),
529  std::move(on_done), std::forward<Contexts>(contexts)...));
530 }
531 
532 } // namespace grpc_core
533 
534 #endif // GRPC_CORE_LIB_PROMISE_ACTIVITY_H
grpc_core::promise_detail::FreestandingActivity::RefIfNonzero
bool RefIfNonzero()
Definition: activity.cc:95
grpc_core::promise_detail::FreestandingActivity
Definition: activity.h:233
grpc_core::Activity::MakeNonOwningWaker
virtual Waker MakeNonOwningWaker()=0
grpc_core::promise_detail::FreestandingActivity::WakeupComplete
void WakeupComplete()
Definition: activity.h:275
grpc_core::promise_detail::PromiseActivity::PromiseActivity
PromiseActivity(F promise_factory, WakeupScheduler wakeup_scheduler, OnDone on_done, Contexts &&... contexts)
Definition: activity.h:345
grpc_core::promise_detail::FreestandingActivity::RefHandle
Handle * RefHandle() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
Definition: activity.cc:97
grpc_core::promise_detail::PromiseActivity::Drop
void Drop() final
Definition: activity.h:423
handle_
static uv_udp_t handle_
Definition: test-udp-dgram-too-big.c:35
grpc_core::promise_detail::FreestandingActivity::GotActionDuringRun
ActionDuringRun GotActionDuringRun() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
Definition: activity.h:269
grpc_core::promise_detail::FreestandingActivity::MakeOwningWaker
Waker MakeOwningWaker() final
Definition: activity.h:235
orphanable.h
log.h
grpc_core::Activity::have_current
static bool have_current()
Definition: activity.h:140
grpc_core::promise_detail::PromiseActivity::Wakeup
void Wakeup() final
Definition: activity.h:404
grpc_core::promise_detail::PromiseActivity
Definition: activity.h:339
grpc_core::Orphanable
Definition: orphanable.h:39
grpc_core::promise_detail::FreestandingActivity::ActionDuringRun
ActionDuringRun
Definition: activity.h:255
grpc_core::promise_detail::PromiseActivity::Cancel
void Cancel() final
Definition: activity.h:380
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::Activity::current
static Activity * current()
Definition: activity.h:124
grpc_core::MutexLock
Definition: src/core/lib/gprpp/sync.h:88
absl::CancelledError
Status CancelledError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:331
grpc_core::promise_detail::FreestandingActivity::ActionDuringRun::kCancel
@ kCancel
grpc_core::Wakeable
Definition: activity.h:47
grpc_core::Wakeable::~Wakeable
~Wakeable()
Definition: activity.h:56
grpc_core::Activity::ScopedActivity::operator=
ScopedActivity & operator=(const ScopedActivity &)=delete
grpc_core::promise_detail::ContextTypeFromHeld
typename ContextHolder< HeldContext >::ContextType ContextTypeFromHeld
Definition: activity.h:205
status
absl::Status status
Definition: rls.cc:251
grpc_core::promise_detail::PromiseActivity::PromiseHolder::~PromiseHolder
~PromiseHolder()
Definition: activity.h:510
grpc_core::Waker::Waker
Waker()
Definition: activity.h:64
grpc_core::Waker::~Waker
~Waker()
Definition: activity.h:65
grpc_core::promise_detail::ContextHolder< Context * >::GetContext
Context * GetContext()
Definition: activity.h:185
grpc_core::promise_detail::FreestandingActivity::refs_
std::atomic< uint32_t > refs_
Definition: activity.h:312
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
grpc_core::Waker::Waker
Waker(Waker &&other) noexcept
Definition: activity.h:70
grpc_core::promise_detail::ContextHolder::value_
Context value_
Definition: activity.h:176
done_
std::atomic< bool > done_
Definition: fuzzing_event_engine_test.cc:57
grpc_core::Activity::ScopedActivity::~ScopedActivity
~ScopedActivity()
Definition: activity.h:148
grpc_core::MakeActivity
ActivityPtr MakeActivity(Factory promise_factory, WakeupScheduler wakeup_scheduler, OnDone on_done, Contexts &&... contexts)
Definition: activity.h:522
grpc_core::promise_detail::ContextHolder
Definition: activity.h:168
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
grpc_core::promise_detail::Context
Definition: core/lib/promise/context.h:37
grpc_core::promise_detail::IntoStatus
absl::Status IntoStatus(absl::StatusOr< T > *status)
Definition: src/core/lib/promise/detail/status.h:32
promise_factory.h
grpc_core::Activity::ScopedActivity::ScopedActivity
ScopedActivity(Activity *activity)
Definition: activity.h:144
grpc_core::Waker::AbslHashValue
friend H AbslHashValue(H h, const Waker &w)
Definition: activity.h:82
grpc_core::promise_detail::PromiseActivity::PromiseHolder
Definition: activity.h:508
grpc_core::promise_detail::PromiseActivity::ABSL_GUARDED_BY
GPR_NO_UNIQUE_ADDRESS bool done_ ABSL_GUARDED_BY(mu())
grpc_core::promise_detail::PromiseActivity::wakeup_scheduled_
GPR_NO_UNIQUE_ADDRESS std::atomic< bool > wakeup_scheduled_
Definition: activity.h:504
grpc_core::promise_detail::ActivityContexts::ScopedContext::ScopedContext
ScopedContext(ActivityContexts *contexts)
Definition: activity.h:215
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc_core::Mutex::Lock
void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION()
Definition: src/core/lib/gprpp/sync.h:69
re2::Result
TestInstance::Result Result
Definition: bloaty/third_party/re2/re2/testing/tester.cc:96
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
ABSL_LOCK_RETURNED
#define ABSL_LOCK_RETURNED(x)
Definition: abseil-cpp/absl/base/thread_annotations.h:174
grpc_core::promise_detail::FreestandingActivity::Cancel
virtual void Cancel()=0
grpc_core::promise_detail::FreestandingActivity::ActionDuringRun::kNone
@ kNone
grpc_core::Waker::operator=
Waker & operator=(const Waker &)=delete
ABSL_EXCLUSIVE_LOCKS_REQUIRED
#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: abseil-cpp/absl/base/thread_annotations.h:145
grpc_core::promise_detail::FreestandingActivity::MakeNonOwningWaker
Waker MakeNonOwningWaker() final
Definition: activity.cc:114
grpc_core::promise_detail::PromiseActivity::RunScheduledWakeup
void RunScheduledWakeup()
Definition: activity.h:371
grpc_core::promise_detail::ContextHolder< Contexts >::ContextType
Contexts ContextType
Definition: activity.h:170
absl::optional
Definition: abseil-cpp/absl/types/internal/optional.h:61
grpc_core::ActivityPtr
OrphanablePtr< Activity > ActivityPtr
Definition: activity.h:163
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
grpc_core::promise_detail::ContextHolder< Context * >::ContextHolder
ContextHolder(Context *value)
Definition: activity.h:184
grpc_core::promise_detail::Context::get
static T * get()
Definition: core/lib/promise/context.h:44
grpc_core::promise_detail::ContextHolder< std::unique_ptr< Context, Deleter > >::value_
std::unique_ptr< Context, Deleter > value_
Definition: activity.h:201
grpc_core::promise_detail::ActivityContexts::ActivityContexts
ActivityContexts(Contexts &&... contexts)
Definition: activity.h:210
grpc_core::promise_detail::FreestandingActivity::ForceImmediateRepoll
void ForceImmediateRepoll() final
Definition: activity.h:246
GPR_NO_UNIQUE_ADDRESS
#define GPR_NO_UNIQUE_ADDRESS
Definition: impl/codegen/port_platform.h:692
grpc_core::promise_detail::PromiseActivity::RunStep
absl::optional< ResultType > RunStep() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu())
Definition: activity.h:453
grpc_core::Waker::Take
Wakeable * Take()
Definition: activity.h:91
F
#define F(b, c, d)
Definition: md4.c:112
stdint.h
H
#define H(b, c, d)
Definition: md4.c:114
grpc_core::promise_detail::ContextHolder::GetContext
Context * GetContext()
Definition: activity.h:173
grpc_core::promise_detail::PromiseFactory< void, F >::Promise
decltype(PromiseFactoryImpl(std::move(f_))) Promise
Definition: promise_factory.h:176
grpc_core::promise_detail::PromiseActivity::ResultType
typename Factory::Promise::Result ResultType
Definition: activity.h:343
grpc_core::Activity::MakeOwningWaker
virtual Waker MakeOwningWaker()=0
grpc_core::promise_detail::PromiseActivity::Step
void Step() ABSL_LOCKS_EXCLUDED(mu())
Definition: activity.h:435
value_
int value_
Definition: orphanable_test.cc:38
grpc_core::Construct
void Construct(T *p, Args &&... args)
Definition: construct_destruct.h:34
value
const char * value
Definition: hpack_parser_table.cc:165
grpc_core::Waker::operator=
Waker & operator=(Waker &&other) noexcept
Definition: activity.h:71
grpc_core::Wakeable::Drop
virtual void Drop()=0
grpc_core::Activity::GPR_THREAD_LOCAL
static GPR_THREAD_LOCAL(Activity *) g_current_activity_
grpc_core::promise_detail::PromiseActivity::Factory
PromiseFactory< void, F > Factory
Definition: activity.h:342
grpc_core::Destruct
void Destruct(T *p)
Definition: construct_destruct.h:27
grpc_core::promise_detail::FreestandingActivity::DropHandle
void DropHandle() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
Definition: activity.cc:109
grpc_core::Mutex
Definition: src/core/lib/gprpp/sync.h:61
grpc_core::Mutex::Unlock
void Unlock() ABSL_UNLOCK_FUNCTION()
Definition: src/core/lib/gprpp/sync.h:70
grpc_core::promise_detail::ContextHolder< Context * >::value_
Context * value_
Definition: activity.h:188
grpc_core::promise_detail::FreestandingActivity::ActionDuringRun::kWakeup
@ kWakeup
client.action
action
Definition: examples/python/xds/client.py:49
grpc_core::Waker
Definition: activity.h:61
ABSL_LOCKS_EXCLUDED
#define ABSL_LOCKS_EXCLUDED(...)
Definition: abseil-cpp/absl/base/thread_annotations.h:163
grpc_core::Activity::ForceWakeup
void ForceWakeup()
Definition: activity.h:112
poll.h
grpc_core::promise_detail::PromiseActivity::PromiseHolder::PromiseHolder
PromiseHolder()
Definition: activity.h:509
grpc_core::OrphanablePtr
std::unique_ptr< T, Deleter > OrphanablePtr
Definition: orphanable.h:64
grpc_core::Activity::ForceImmediateRepoll
virtual void ForceImmediateRepoll()=0
grpc_core::promise_detail::FreestandingActivity::Orphan
void Orphan() final
Definition: activity.h:241
fix_build_deps.r
r
Definition: fix_build_deps.py:491
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc_core::promise_detail::ContextHolder< std::unique_ptr< Context, Deleter > >::GetContext
Context * GetContext()
Definition: activity.h:198
grpc_core::promise_detail::PromiseActivity::MarkDone
void MarkDone() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu())
Definition: activity.h:427
status.h
grpc_core::promise_detail::PromiseActivity::on_done_
GPR_NO_UNIQUE_ADDRESS OnDone on_done_
Definition: activity.h:500
grpc_core::promise_detail::PromiseActivity::StepLoop
absl::optional< ResultType > StepLoop() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu())
Definition: activity.h:472
tls.h
grpc_core::promise_detail::FreestandingActivity::~FreestandingActivity
~FreestandingActivity() override
Definition: activity.h:261
grpc_core::Activity::ScopedActivity::prior_activity_
Activity *const prior_activity_
Definition: activity.h:153
grpc_core::promise_detail::FreestandingActivity::Unref
void Unref()
Definition: activity.h:293
context.h
grpc_core::promise_detail::FreestandingActivity::mu_
Mutex mu_
Definition: activity.h:309
grpc_core::promise_detail::PromiseActivity::~PromiseActivity
~PromiseActivity() override
Definition: activity.h:364
grpc_core::promise_detail::PromiseActivity::wakeup_scheduler_
GPR_NO_UNIQUE_ADDRESS WakeupScheduler wakeup_scheduler_
Definition: activity.h:498
grpc_core::promise_detail::PromiseFactory< void, F >
Definition: promise_factory.h:170
grpc_core::promise_detail::PromiseActivity::Promise
typename Factory::Promise Promise
Definition: activity.h:496
grpc_core::Waker::Wakeup
void Wakeup()
Definition: activity.h:77
grpc_core::promise_detail::PromiseActivity::Start
absl::optional< ResultType > Start(Factory promise_factory) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu())
Definition: activity.h:462
absl::forward
constexpr T && forward(absl::remove_reference_t< T > &t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:230
grpc_core::promise_detail::ActivityContexts::ScopedContext
Definition: activity.h:213
grpc_core::promise_detail::FreestandingActivity::SetActionDuringRun
void SetActionDuringRun(ActionDuringRun action) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
Definition: activity.h:279
grpc_core::promise_detail::ActivityContexts
Definition: activity.h:208
grpc_core::Activity
Definition: activity.h:105
grpc_core::Activity::ScopedActivity
Definition: activity.h:142
grpc_core::Waker::Waker
Waker(Wakeable *wakeable)
Definition: activity.h:63
grpc_core::promise_detail::FreestandingActivity::ABSL_GUARDED_BY
ActionDuringRun action_during_run_ ABSL_GUARDED_BY(mu_)
construct_destruct.h
grpc_core::Wakeable::Wakeup
virtual void Wakeup()=0
grpc_core::Waker::wakeable_
Wakeable * wakeable_
Definition: activity.h:93
grpc_core::promise_detail::ContextHolder< std::unique_ptr< Context, Deleter > >::ContextHolder
ContextHolder(std::unique_ptr< Context, Deleter > value)
Definition: activity.h:196
grpc_core::Mutex::AssertHeld
void AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK()
Definition: src/core/lib/gprpp/sync.h:74
grpc_core::Activity::is_current
bool is_current() const
Definition: activity.h:138
grpc_core::Waker::operator==
bool operator==(const Waker &other) const noexcept
Definition: activity.h:86
sync.h
grpc_core::promise_detail::ContextHolder::ContextHolder
ContextHolder(Context value)
Definition: activity.h:172
absl::exchange
T exchange(T &obj, U &&new_value)
Definition: abseil-cpp/absl/utility/utility.h:314
grpc_core::promise_detail::PromiseActivity::PromiseHolder::promise
GPR_NO_UNIQUE_ADDRESS Promise promise
Definition: activity.h:511
port_platform.h
grpc_core::promise_detail::FreestandingActivity::Ref
void Ref()
Definition: activity.h:292
grpc_core::promise_detail::FreestandingActivity::mu
Mutex * mu() ABSL_LOCK_RETURNED(mu_)
Definition: activity.h:284


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:29