• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/callback.h"
12 
13 #include "rtc_base/bind.h"
14 #include "rtc_base/keep_ref_until_done.h"
15 #include "rtc_base/ref_count.h"
16 #include "test/gtest.h"
17 
18 namespace rtc {
19 
20 namespace {
21 
f()22 void f() {}
g()23 int g() {
24   return 42;
25 }
h(int x)26 int h(int x) {
27   return x * x;
28 }
i(int & x)29 void i(int& x) {
30   x *= x;
31 }  // NOLINT: Testing refs
32 
33 struct BindTester {
artc::__anon257e24250111::BindTester34   int a() { return 24; }
brtc::__anon257e24250111::BindTester35   int b(int x) const { return x * x; }
36 };
37 
38 class RefCountedBindTester : public RefCountInterface {
39  public:
RefCountedBindTester()40   RefCountedBindTester() : count_(0) {}
AddRef() const41   void AddRef() const override { ++count_; }
Release() const42   RefCountReleaseStatus Release() const override {
43     --count_;
44     return count_ == 0 ? RefCountReleaseStatus::kDroppedLastRef
45                        : RefCountReleaseStatus::kOtherRefsRemained;
46   }
RefCount() const47   int RefCount() const { return count_; }
48 
49  private:
50   mutable int count_;
51 };
52 
53 }  // namespace
54 
TEST(CallbackTest,VoidReturn)55 TEST(CallbackTest, VoidReturn) {
56   Callback0<void> cb;
57   EXPECT_TRUE(cb.empty());
58   cb();  // Executing an empty callback should not crash.
59   cb = Callback0<void>(&f);
60   EXPECT_FALSE(cb.empty());
61   cb();
62 }
63 
TEST(CallbackTest,IntReturn)64 TEST(CallbackTest, IntReturn) {
65   Callback0<int> cb;
66   EXPECT_TRUE(cb.empty());
67   cb = Callback0<int>(&g);
68   EXPECT_FALSE(cb.empty());
69   EXPECT_EQ(42, cb());
70   EXPECT_EQ(42, cb());
71 }
72 
TEST(CallbackTest,OneParam)73 TEST(CallbackTest, OneParam) {
74   Callback1<int, int> cb1(&h);
75   EXPECT_FALSE(cb1.empty());
76   EXPECT_EQ(9, cb1(-3));
77   EXPECT_EQ(100, cb1(10));
78 
79   // Try clearing a callback.
80   cb1 = Callback1<int, int>();
81   EXPECT_TRUE(cb1.empty());
82 
83   // Try a callback with a ref parameter.
84   Callback1<void, int&> cb2(&i);
85   int x = 3;
86   cb2(x);
87   EXPECT_EQ(9, x);
88   cb2(x);
89   EXPECT_EQ(81, x);
90 }
91 
TEST(CallbackTest,WithBind)92 TEST(CallbackTest, WithBind) {
93   BindTester t;
94   Callback0<int> cb1 = Bind(&BindTester::a, &t);
95   EXPECT_EQ(24, cb1());
96   EXPECT_EQ(24, cb1());
97   cb1 = Bind(&BindTester::b, &t, 10);
98   EXPECT_EQ(100, cb1());
99   EXPECT_EQ(100, cb1());
100   cb1 = Bind(&BindTester::b, &t, 5);
101   EXPECT_EQ(25, cb1());
102   EXPECT_EQ(25, cb1());
103 }
104 
TEST(KeepRefUntilDoneTest,simple)105 TEST(KeepRefUntilDoneTest, simple) {
106   RefCountedBindTester t;
107   EXPECT_EQ(0, t.RefCount());
108   {
109     Callback0<void> cb = KeepRefUntilDone(&t);
110     EXPECT_EQ(1, t.RefCount());
111     cb();
112     EXPECT_EQ(1, t.RefCount());
113     cb();
114     EXPECT_EQ(1, t.RefCount());
115   }
116   EXPECT_EQ(0, t.RefCount());
117 }
118 
TEST(KeepRefUntilDoneTest,copy)119 TEST(KeepRefUntilDoneTest, copy) {
120   RefCountedBindTester t;
121   EXPECT_EQ(0, t.RefCount());
122   Callback0<void> cb2;
123   {
124     Callback0<void> cb = KeepRefUntilDone(&t);
125     EXPECT_EQ(1, t.RefCount());
126     cb2 = cb;
127   }
128   EXPECT_EQ(1, t.RefCount());
129   cb2 = Callback0<void>();
130   EXPECT_EQ(0, t.RefCount());
131 }
132 
TEST(KeepRefUntilDoneTest,scopedref)133 TEST(KeepRefUntilDoneTest, scopedref) {
134   RefCountedBindTester t;
135   EXPECT_EQ(0, t.RefCount());
136   {
137     scoped_refptr<RefCountedBindTester> t_scoped_ref(&t);
138     Callback0<void> cb = KeepRefUntilDone(t_scoped_ref);
139     t_scoped_ref = nullptr;
140     EXPECT_EQ(1, t.RefCount());
141     cb();
142     EXPECT_EQ(1, t.RefCount());
143   }
144   EXPECT_EQ(0, t.RefCount());
145 }
146 
147 }  // namespace rtc
148