xref: /aosp_15_r20/external/grpc-grpc/test/core/gprpp/dual_ref_counted_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 // Copyright 2020 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "src/core/lib/gprpp/dual_ref_counted.h"
18 
19 #include <memory>
20 
21 #include "gtest/gtest.h"
22 
23 #include "test/core/util/test_config.h"
24 
25 namespace grpc_core {
26 namespace testing {
27 namespace {
28 
29 class Foo : public DualRefCounted<Foo> {
30  public:
31   Foo() = default;
~Foo()32   ~Foo() override { GPR_ASSERT(shutting_down_); }
33 
Orphaned()34   void Orphaned() override { shutting_down_ = true; }
35 
36  private:
37   bool shutting_down_ = false;
38 };
39 
TEST(DualRefCounted,Basic)40 TEST(DualRefCounted, Basic) {
41   Foo* foo = new Foo();
42   foo->Unref();
43 }
44 
TEST(DualRefCounted,ExtraRef)45 TEST(DualRefCounted, ExtraRef) {
46   Foo* foo = new Foo();
47   foo->Ref().release();
48   foo->Unref();
49   foo->Unref();
50 }
51 
TEST(DualRefCounted,ExtraWeakRef)52 TEST(DualRefCounted, ExtraWeakRef) {
53   Foo* foo = new Foo();
54   foo->WeakRef().release();
55   foo->Unref();
56   foo->WeakUnref();
57 }
58 
TEST(DualRefCounted,RefIfNonZero)59 TEST(DualRefCounted, RefIfNonZero) {
60   Foo* foo = new Foo();
61   foo->WeakRef().release();
62   {
63     RefCountedPtr<Foo> foop = foo->RefIfNonZero();
64     EXPECT_NE(foop.get(), nullptr);
65   }
66   foo->Unref();
67   {
68     RefCountedPtr<Foo> foop = foo->RefIfNonZero();
69     EXPECT_EQ(foop.get(), nullptr);
70   }
71   foo->WeakUnref();
72 }
73 
TEST(DualRefCounted,RefAndWeakRefAsSubclass)74 TEST(DualRefCounted, RefAndWeakRefAsSubclass) {
75   class Bar : public Foo {};
76   Foo* foo = new Bar();
77   RefCountedPtr<Bar> barp = foo->RefAsSubclass<Bar>();
78   barp.release();
79   barp = foo->RefAsSubclass<Bar>(DEBUG_LOCATION, "test");
80   barp.release();
81   WeakRefCountedPtr<Bar> weak_barp = foo->WeakRefAsSubclass<Bar>();
82   weak_barp.release();
83   weak_barp = foo->WeakRefAsSubclass<Bar>(DEBUG_LOCATION, "test");
84   weak_barp.release();
85   foo->WeakUnref();
86   foo->WeakUnref();
87   foo->Unref();
88   foo->Unref();
89   foo->Unref();
90 }
91 
92 class FooWithTracing : public DualRefCounted<FooWithTracing> {
93  public:
FooWithTracing()94   FooWithTracing() : DualRefCounted("FooWithTracing") {}
~FooWithTracing()95   ~FooWithTracing() override { GPR_ASSERT(shutting_down_); }
96 
Orphaned()97   void Orphaned() override { shutting_down_ = true; }
98 
99  private:
100   bool shutting_down_ = false;
101 };
102 
TEST(DualRefCountedWithTracing,Basic)103 TEST(DualRefCountedWithTracing, Basic) {
104   FooWithTracing* foo = new FooWithTracing();
105   foo->Ref(DEBUG_LOCATION, "extra_ref").release();
106   foo->Unref(DEBUG_LOCATION, "extra_ref");
107   foo->WeakRef(DEBUG_LOCATION, "extra_ref").release();
108   foo->WeakUnref(DEBUG_LOCATION, "extra_ref");
109   // Can use the no-argument methods, too.
110   foo->Ref().release();
111   foo->Unref();
112   foo->WeakRef().release();
113   foo->WeakUnref();
114   foo->Unref(DEBUG_LOCATION, "original_ref");
115 }
116 
117 }  // namespace
118 }  // namespace testing
119 }  // namespace grpc_core
120 
main(int argc,char ** argv)121 int main(int argc, char** argv) {
122   grpc::testing::TestEnvironment env(&argc, argv);
123   ::testing::InitGoogleTest(&argc, argv);
124   return RUN_ALL_TESTS();
125 }
126