• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include "src/core/lib/gprpp/ref_counted.h"
20 
21 #include <gtest/gtest.h>
22 
23 #include "src/core/lib/gprpp/memory.h"
24 #include "test/core/util/test_config.h"
25 
26 namespace grpc_core {
27 namespace testing {
28 namespace {
29 
30 class Foo : public RefCounted<Foo> {
31  public:
Foo()32   Foo() {
33     static_assert(std::has_virtual_destructor<Foo>::value,
34                   "PolymorphicRefCount doesn't have a virtual dtor");
35   }
36 };
37 
TEST(RefCounted,Basic)38 TEST(RefCounted, Basic) {
39   Foo* foo = new Foo();
40   foo->Unref();
41 }
42 
TEST(RefCounted,ExtraRef)43 TEST(RefCounted, ExtraRef) {
44   Foo* foo = new Foo();
45   RefCountedPtr<Foo> foop = foo->Ref();
46   foop.release();
47   foo->Unref();
48   foo->Unref();
49 }
50 
51 class FooNonPolymorphic
52     : public RefCounted<FooNonPolymorphic, NonPolymorphicRefCount> {
53  public:
FooNonPolymorphic()54   FooNonPolymorphic() {
55     static_assert(!std::has_virtual_destructor<FooNonPolymorphic>::value,
56                   "NonPolymorphicRefCount has a virtual dtor");
57   }
58 };
59 
TEST(RefCountedNonPolymorphic,Basic)60 TEST(RefCountedNonPolymorphic, Basic) {
61   FooNonPolymorphic* foo = new FooNonPolymorphic();
62   foo->Unref();
63 }
64 
TEST(RefCountedNonPolymorphic,ExtraRef)65 TEST(RefCountedNonPolymorphic, ExtraRef) {
66   FooNonPolymorphic* foo = new FooNonPolymorphic();
67   RefCountedPtr<FooNonPolymorphic> foop = foo->Ref();
68   foop.release();
69   foo->Unref();
70   foo->Unref();
71 }
72 
73 // Note: We use DebugOnlyTraceFlag instead of TraceFlag to ensure that
74 // things build properly in both debug and non-debug cases.
75 DebugOnlyTraceFlag foo_tracer(true, "foo");
76 
77 class FooWithTracing : public RefCounted<FooWithTracing> {
78  public:
FooWithTracing()79   FooWithTracing() : RefCounted(&foo_tracer) {}
80 };
81 
TEST(RefCountedWithTracing,Basic)82 TEST(RefCountedWithTracing, Basic) {
83   FooWithTracing* foo = new FooWithTracing();
84   RefCountedPtr<FooWithTracing> foop = foo->Ref(DEBUG_LOCATION, "extra_ref");
85   foop.release();
86   foo->Unref(DEBUG_LOCATION, "extra_ref");
87   // Can use the no-argument methods, too.
88   foop = foo->Ref();
89   foop.release();
90   foo->Unref();
91   foo->Unref(DEBUG_LOCATION, "original_ref");
92 }
93 
94 class FooNonPolymorphicWithTracing
95     : public RefCounted<FooNonPolymorphicWithTracing, NonPolymorphicRefCount> {
96  public:
FooNonPolymorphicWithTracing()97   FooNonPolymorphicWithTracing() : RefCounted(&foo_tracer) {}
98 };
99 
TEST(RefCountedNonPolymorphicWithTracing,Basic)100 TEST(RefCountedNonPolymorphicWithTracing, Basic) {
101   FooNonPolymorphicWithTracing* foo = new FooNonPolymorphicWithTracing();
102   RefCountedPtr<FooNonPolymorphicWithTracing> foop =
103       foo->Ref(DEBUG_LOCATION, "extra_ref");
104   foop.release();
105   foo->Unref(DEBUG_LOCATION, "extra_ref");
106   // Can use the no-argument methods, too.
107   foop = foo->Ref();
108   foop.release();
109   foo->Unref();
110   foo->Unref(DEBUG_LOCATION, "original_ref");
111 }
112 
113 }  // namespace
114 }  // namespace testing
115 }  // namespace grpc_core
116 
main(int argc,char ** argv)117 int main(int argc, char** argv) {
118   grpc::testing::TestEnvironment env(argc, argv);
119   ::testing::InitGoogleTest(&argc, argv);
120   return RUN_ALL_TESTS();
121 }
122