activity.cc
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 
16 
18 
19 #include <stddef.h>
20 
22 
23 namespace grpc_core {
24 
26 // GLOBALS
27 
28 GPR_THREAD_LOCAL(Activity*) Activity::g_current_activity_{nullptr};
29 
30 namespace promise_detail {
31 
33 // HELPER TYPES
34 
35 // Weak handle to an Activity.
36 // Handle can persist while Activity goes away.
37 class FreestandingActivity::Handle final : public Wakeable {
38  public:
39  explicit Handle(FreestandingActivity* activity) : activity_(activity) {}
40 
41  // Ref the Handle (not the activity).
42  void Ref() { refs_.fetch_add(1, std::memory_order_relaxed); }
43 
44  // Activity is going away... drop its reference and sever the connection back.
46  mu_.Lock();
47  GPR_ASSERT(activity_ != nullptr);
48  activity_ = nullptr;
49  mu_.Unlock();
50  Unref();
51  }
52 
53  // Activity needs to wake up (if it still exists!) - wake it up, and drop the
54  // ref that was kept for this handle.
55  void Wakeup() override ABSL_LOCKS_EXCLUDED(mu_) {
56  mu_.Lock();
57  // Note that activity refcount can drop to zero, but we could win the lock
58  // against DropActivity, so we need to only increase activities refcount if
59  // it is non-zero.
60  if (activity_ && activity_->RefIfNonzero()) {
61  FreestandingActivity* activity = activity_;
62  mu_.Unlock();
63  // Activity still exists and we have a reference: wake it up, which will
64  // drop the ref.
65  activity->Wakeup();
66  } else {
67  // Could not get the activity - it's either gone or going. No need to wake
68  // it up!
69  mu_.Unlock();
70  }
71  // Drop the ref to the handle (we have one ref = one wakeup semantics).
72  Unref();
73  }
74 
75  void Drop() override { Unref(); }
76 
77  private:
78  // Unref the Handle (not the activity).
79  void Unref() {
80  if (1 == refs_.fetch_sub(1, std::memory_order_acq_rel)) {
81  delete this;
82  }
83  }
84 
85  // Two initial refs: one for the waiter that caused instantiation, one for the
86  // activity.
87  std::atomic<size_t> refs_{2};
90 };
91 
93 // ACTIVITY IMPLEMENTATION
94 
96 
98  if (handle_ == nullptr) {
99  // No handle created yet - construct it and return it.
100  handle_ = new Handle(this);
101  return handle_;
102  } else {
103  // Already had to create a handle, ref & return it.
104  handle_->Ref();
105  return handle_;
106  }
107 }
108 
110  handle_->DropActivity();
111  handle_ = nullptr;
112 }
113 
115  mu_.AssertHeld();
116  return Waker(RefHandle());
117 }
118 
119 } // namespace promise_detail
120 } // namespace grpc_core
grpc_core::promise_detail::FreestandingActivity::RefIfNonzero
bool RefIfNonzero()
Definition: activity.cc:95
grpc_core::promise_detail::FreestandingActivity
Definition: activity.h:233
atomic_utils.h
grpc_core::promise_detail::FreestandingActivity::RefHandle
Handle * RefHandle() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_)
Definition: activity.cc:97
handle_
static uv_udp_t handle_
Definition: test-udp-dgram-too-big.c:35
grpc_core
Definition: call_metric_recorder.h:31
grpc_core::Wakeable
Definition: activity.h:47
grpc_core::promise_detail::FreestandingActivity::refs_
std::atomic< uint32_t > refs_
Definition: activity.h:312
grpc_core::promise_detail::FreestandingActivity::Handle::ABSL_ACQUIRED_AFTER
Mutex mu_ ABSL_ACQUIRED_AFTER(activity_->mu_)
grpc_core::promise_detail::FreestandingActivity::Handle::Drop
void Drop() override
Definition: activity.cc:75
grpc_core::promise_detail::FreestandingActivity::Handle::Handle
Handle(FreestandingActivity *activity)
Definition: activity.cc:39
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
grpc_core::promise_detail::FreestandingActivity::MakeNonOwningWaker
Waker MakeNonOwningWaker() final
Definition: activity.cc:114
GPR_THREAD_LOCAL
#define GPR_THREAD_LOCAL(type)
Definition: tls.h:151
grpc_core::promise_detail::FreestandingActivity::Handle::Ref
void Ref()
Definition: activity.cc:42
activity_
ActivityPtr activity_
Definition: promise_fuzzer.cc:315
grpc_core::promise_detail::FreestandingActivity::Handle::ABSL_GUARDED_BY
FreestandingActivity *activity_ ABSL_GUARDED_BY(mu_)
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::FreestandingActivity::Handle::refs_
std::atomic< size_t > refs_
Definition: activity.cc:87
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::promise_detail::FreestandingActivity::Handle::Unref
void Unref()
Definition: activity.cc:79
grpc_core::promise_detail::FreestandingActivity::mu_
Mutex mu_
Definition: activity.h:309
grpc_core::IncrementIfNonzero
bool IncrementIfNonzero(std::atomic< T > *p)
Definition: atomic_utils.h:31
grpc_core::promise_detail::FreestandingActivity::Handle
Definition: activity.cc:37
grpc_core::promise_detail::FreestandingActivity::Handle::DropActivity
void DropActivity() ABSL_LOCKS_EXCLUDED(mu_)
Definition: activity.cc:45
activity.h
grpc_core::Wakeable::Wakeup
virtual void Wakeup()=0
grpc_core::Mutex::AssertHeld
void AssertHeld() ABSL_ASSERT_EXCLUSIVE_LOCK()
Definition: src/core/lib/gprpp/sync.h:74
grpc_core::promise_detail::FreestandingActivity::Handle::Wakeup
void Wakeup() override ABSL_LOCKS_EXCLUDED(mu_)
Definition: activity.cc:55
port_platform.h


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