blob: 078710b2ca6c394aa23976d4864b735b1dcffdb5 [file] [log] [blame]
deadbeef8290ddf2017-07-11 16:56:05 -07001/*
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 <memory>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/constructormagic.h"
14#include "rtc_base/gunit.h"
15#include "rtc_base/signalthread.h"
16#include "rtc_base/thread.h"
deadbeef8290ddf2017-07-11 16:56:05 -070017
18using namespace rtc;
19
20// 10 seconds.
21static const int kTimeout = 10000;
22
23class SignalThreadTest : public testing::Test, public sigslot::has_slots<> {
24 public:
25 class SlowSignalThread : public SignalThread {
26 public:
27 SlowSignalThread(SignalThreadTest* harness) : harness_(harness) {}
28
Steve Anton9de3aac2017-10-24 10:08:26 -070029 ~SlowSignalThread() override {
deadbeef8290ddf2017-07-11 16:56:05 -070030 EXPECT_EQ(harness_->main_thread_, Thread::Current());
31 ++harness_->thread_deleted_;
32 }
33
34 const SignalThreadTest* harness() { return harness_; }
35
36 protected:
Steve Anton9de3aac2017-10-24 10:08:26 -070037 void OnWorkStart() override {
deadbeef8290ddf2017-07-11 16:56:05 -070038 ASSERT_TRUE(harness_ != nullptr);
39 ++harness_->thread_started_;
40 EXPECT_EQ(harness_->main_thread_, Thread::Current());
41 EXPECT_FALSE(worker()->RunningForTest()); // not started yet
42 }
43
Steve Anton9de3aac2017-10-24 10:08:26 -070044 void OnWorkStop() override {
deadbeef8290ddf2017-07-11 16:56:05 -070045 ++harness_->thread_stopped_;
46 EXPECT_EQ(harness_->main_thread_, Thread::Current());
47 EXPECT_TRUE(worker()->RunningForTest()); // not stopped yet
48 }
49
Steve Anton9de3aac2017-10-24 10:08:26 -070050 void OnWorkDone() override {
deadbeef8290ddf2017-07-11 16:56:05 -070051 ++harness_->thread_done_;
52 EXPECT_EQ(harness_->main_thread_, Thread::Current());
53 EXPECT_TRUE(worker()->RunningForTest()); // not stopped yet
54 }
55
Steve Anton9de3aac2017-10-24 10:08:26 -070056 void DoWork() override {
deadbeef8290ddf2017-07-11 16:56:05 -070057 EXPECT_NE(harness_->main_thread_, Thread::Current());
58 EXPECT_EQ(worker(), Thread::Current());
59 Thread::Current()->socketserver()->Wait(250, false);
60 }
61
62 private:
63 SignalThreadTest* harness_;
64 RTC_DISALLOW_COPY_AND_ASSIGN(SlowSignalThread);
65 };
66
67 void OnWorkComplete(rtc::SignalThread* thread) {
68 SlowSignalThread* t = static_cast<SlowSignalThread*>(thread);
69 EXPECT_EQ(t->harness(), this);
70 EXPECT_EQ(main_thread_, Thread::Current());
71
72 ++thread_completed_;
73 if (!called_release_) {
74 thread->Release();
75 }
76 }
77
Steve Anton9de3aac2017-10-24 10:08:26 -070078 void SetUp() override {
deadbeef8290ddf2017-07-11 16:56:05 -070079 main_thread_ = Thread::Current();
80 thread_ = new SlowSignalThread(this);
81 thread_->SignalWorkDone.connect(this, &SignalThreadTest::OnWorkComplete);
82 called_release_ = false;
83 thread_started_ = 0;
84 thread_done_ = 0;
85 thread_completed_ = 0;
86 thread_stopped_ = 0;
87 thread_deleted_ = 0;
88 }
89
deadbeef8290ddf2017-07-11 16:56:05 -070090 void ExpectState(int started,
91 int done,
92 int completed,
93 int stopped,
94 int deleted) {
95 EXPECT_EQ(started, thread_started_);
96 EXPECT_EQ(done, thread_done_);
97 EXPECT_EQ(completed, thread_completed_);
98 EXPECT_EQ(stopped, thread_stopped_);
99 EXPECT_EQ(deleted, thread_deleted_);
100 }
101
102 void ExpectStateWait(int started,
103 int done,
104 int completed,
105 int stopped,
106 int deleted,
107 int timeout) {
108 EXPECT_EQ_WAIT(started, thread_started_, timeout);
109 EXPECT_EQ_WAIT(done, thread_done_, timeout);
110 EXPECT_EQ_WAIT(completed, thread_completed_, timeout);
111 EXPECT_EQ_WAIT(stopped, thread_stopped_, timeout);
112 EXPECT_EQ_WAIT(deleted, thread_deleted_, timeout);
113 }
114
115 Thread* main_thread_;
116 SlowSignalThread* thread_;
117 bool called_release_;
118
119 int thread_started_;
120 int thread_done_;
121 int thread_completed_;
122 int thread_stopped_;
123 int thread_deleted_;
124};
125
126class OwnerThread : public Thread, public sigslot::has_slots<> {
127 public:
128 explicit OwnerThread(SignalThreadTest* harness)
129 : harness_(harness), has_run_(false) {}
130
Steve Anton9de3aac2017-10-24 10:08:26 -0700131 ~OwnerThread() override { Stop(); }
deadbeef8290ddf2017-07-11 16:56:05 -0700132
Steve Anton9de3aac2017-10-24 10:08:26 -0700133 void Run() override {
deadbeef8290ddf2017-07-11 16:56:05 -0700134 SignalThreadTest::SlowSignalThread* signal_thread =
135 new SignalThreadTest::SlowSignalThread(harness_);
136 signal_thread->SignalWorkDone.connect(this, &OwnerThread::OnWorkDone);
137 signal_thread->Start();
138 Thread::Current()->socketserver()->Wait(100, false);
139 signal_thread->Release();
140 // Delete |signal_thread|.
141 signal_thread->Destroy(true);
142 has_run_ = true;
143 }
144
145 bool has_run() { return has_run_; }
146 void OnWorkDone(SignalThread* signal_thread) {
147 FAIL() << " This shouldn't get called.";
148 }
149
150 private:
151 SignalThreadTest* harness_;
152 bool has_run_;
153 RTC_DISALLOW_COPY_AND_ASSIGN(OwnerThread);
154};
155
156// Test for when the main thread goes away while the
157// signal thread is still working. This may happen
158// when shutting down the process.
159TEST_F(SignalThreadTest, OwnerThreadGoesAway) {
160 // We don't use |thread_| for this test, so destroy it.
161 thread_->Destroy(true);
162
163 {
164 std::unique_ptr<OwnerThread> owner(new OwnerThread(this));
165 main_thread_ = owner.get();
166 owner->Start();
167 while (!owner->has_run()) {
168 Thread::Current()->socketserver()->Wait(10, false);
169 }
170 }
171 // At this point the main thread has gone away.
172 // Give the SignalThread a little time to do its callback,
173 // which will crash if the signal thread doesn't handle
174 // this situation well.
175 Thread::Current()->socketserver()->Wait(500, false);
176}
177
178TEST_F(SignalThreadTest, ThreadFinishes) {
179 thread_->Start();
180 ExpectState(1, 0, 0, 0, 0);
181 ExpectStateWait(1, 1, 1, 0, 1, kTimeout);
182}
183
184TEST_F(SignalThreadTest, ReleasedThreadFinishes) {
185 thread_->Start();
186 ExpectState(1, 0, 0, 0, 0);
187 thread_->Release();
188 called_release_ = true;
189 ExpectState(1, 0, 0, 0, 0);
190 ExpectStateWait(1, 1, 1, 0, 1, kTimeout);
191}
192
193TEST_F(SignalThreadTest, DestroyedThreadCleansUp) {
194 thread_->Start();
195 ExpectState(1, 0, 0, 0, 0);
196 thread_->Destroy(true);
197 ExpectState(1, 0, 0, 1, 1);
198 Thread::Current()->ProcessMessages(0);
199 ExpectState(1, 0, 0, 1, 1);
200}
201
202TEST_F(SignalThreadTest, DeferredDestroyedThreadCleansUp) {
203 thread_->Start();
204 ExpectState(1, 0, 0, 0, 0);
205 thread_->Destroy(false);
206 ExpectState(1, 0, 0, 1, 0);
207 ExpectStateWait(1, 1, 0, 1, 1, kTimeout);
208}