Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: base/threading/thread_unittest.cc

Issue 2135413003: Add |joinable| to Thread::Options (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Checking |run_loop_| doesn't work as ThreadMain could have not hit yet in tests -- introduce |using… Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/threading/thread.h" 5 #include "base/threading/thread.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/location.h"
13 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
15 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 14 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
15 #include "base/threading/platform_thread.h"
16 #include "build/build_config.h" 16 #include "build/build_config.h"
17 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "testing/platform_test.h" 18 #include "testing/platform_test.h"
19 19
20 // Death tests misbehave on Android.
21 // TODO(gab): Remove this when https://codereview.chromium.org/2162053006
22 // lands.
23 #if DCHECK_IS_ON() && defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
24 #define EXPECT_DCHECK_DEATH(statement, regex) EXPECT_DEATH(statement, regex)
25 #else
26 #define EXPECT_DCHECK_DEATH(statement, regex)
27 #endif
28
20 using base::Thread; 29 using base::Thread;
21 30
22 typedef PlatformTest ThreadTest; 31 typedef PlatformTest ThreadTest;
23 32
24 namespace { 33 namespace {
25 34
26 void ToggleValue(bool* value) { 35 void ToggleValue(bool* value) {
27 ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean " 36 ANNOTATE_BENIGN_RACE(value, "Test-only data race on boolean "
28 "in base/thread_unittest"); 37 "in base/thread_unittest");
29 *value = !*value; 38 *value = !*value;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 EXPECT_TRUE(a.message_loop()); 166 EXPECT_TRUE(a.message_loop());
158 EXPECT_TRUE(a.IsRunning()); 167 EXPECT_TRUE(a.IsRunning());
159 168
160 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, 169 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
161 base::WaitableEvent::InitialState::NOT_SIGNALED); 170 base::WaitableEvent::InitialState::NOT_SIGNALED);
162 a.task_runner()->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal, 171 a.task_runner()->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal,
163 base::Unretained(&event))); 172 base::Unretained(&event)));
164 event.Wait(); 173 event.Wait();
165 } 174 }
166 175
167 TEST_F(ThreadTest, TwoTasks) { 176 TEST_F(ThreadTest, StartWithOptions_NonJoinable) {
177 Thread a("StartNonJoinable");
178 Thread::Options options;
179 options.joinable = false;
180 EXPECT_TRUE(a.StartWithOptions(options));
181 EXPECT_TRUE(a.message_loop());
182 EXPECT_TRUE(a.IsRunning());
183
184 // Without this call this test is racy. The above IsRunning() succeeds because
185 // of an early-return condition while between Start() and Stop(), after
186 // invoking Stop() below this early-return condition is no longer satisfied
187 // and the real |is_running_| bit has to be checked. It could still be false
188 // if the message loop hasn't started for real in practice. This is only a
189 // requirement for this test because the non-joinable thread makes it possible
190 // to return from Stop() before the thread has even started.
191 EXPECT_TRUE(a.WaitUntilThreadStarted());
192
193 // Make the thread block until |block_event| is signaled.
194 base::WaitableEvent block_event(
195 base::WaitableEvent::ResetPolicy::AUTOMATIC,
196 base::WaitableEvent::InitialState::NOT_SIGNALED);
197 a.task_runner()->PostTask(
198 FROM_HERE,
199 base::Bind(&base::WaitableEvent::Wait, base::Unretained(&block_event)));
200
201 // Stop() shouldn't block despite the thread still being alive.
202 a.Stop();
203 EXPECT_TRUE(a.IsRunning());
204
205 // Unblock the task and give a bit of extra time to unwind QuitWhenIdle().
206 block_event.Signal();
207 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
208
209 // The thread should now have stopped on its own.
210 EXPECT_FALSE(a.IsRunning());
211 }
212
213 TEST_F(ThreadTest, TwoTasksOnJoinableThread) {
168 bool was_invoked = false; 214 bool was_invoked = false;
169 { 215 {
170 Thread a("TwoTasks"); 216 Thread a("TwoTasksOnJoinableThread");
171 EXPECT_TRUE(a.Start()); 217 EXPECT_TRUE(a.Start());
172 EXPECT_TRUE(a.message_loop()); 218 EXPECT_TRUE(a.message_loop());
173 219
174 // Test that all events are dispatched before the Thread object is 220 // Test that all events are dispatched before the Thread object is
175 // destroyed. We do this by dispatching a sleep event before the 221 // destroyed. We do this by dispatching a sleep event before the
176 // event that will toggle our sentinel value. 222 // event that will toggle our sentinel value.
177 a.task_runner()->PostTask( 223 a.task_runner()->PostTask(
178 FROM_HERE, base::Bind(static_cast<void (*)(base::TimeDelta)>( 224 FROM_HERE, base::Bind(static_cast<void (*)(base::TimeDelta)>(
179 &base::PlatformThread::Sleep), 225 &base::PlatformThread::Sleep),
180 base::TimeDelta::FromMilliseconds(20))); 226 base::TimeDelta::FromMilliseconds(20)));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 EXPECT_FALSE(a.IsRunning()); 270 EXPECT_FALSE(a.IsRunning());
225 271
226 EXPECT_TRUE(a.Start()); 272 EXPECT_TRUE(a.Start());
227 EXPECT_TRUE(a.message_loop()); 273 EXPECT_TRUE(a.message_loop());
228 EXPECT_TRUE(a.IsRunning()); 274 EXPECT_TRUE(a.IsRunning());
229 a.Stop(); 275 a.Stop();
230 EXPECT_FALSE(a.message_loop()); 276 EXPECT_FALSE(a.message_loop());
231 EXPECT_FALSE(a.IsRunning()); 277 EXPECT_FALSE(a.IsRunning());
232 } 278 }
233 279
280 TEST_F(ThreadTest, StartTwiceNonJoinableNotAllowed) {
281 Thread a("StartTwiceNonJoinable");
282
283 Thread::Options options;
284 options.joinable = false;
285 EXPECT_TRUE(a.StartWithOptions(options));
286 EXPECT_TRUE(a.message_loop());
287 EXPECT_TRUE(a.IsRunning());
288
289 // Signaled when last task on |a| is processed.
290 base::WaitableEvent last_task_event(
291 base::WaitableEvent::ResetPolicy::AUTOMATIC,
292 base::WaitableEvent::InitialState::NOT_SIGNALED);
293 a.task_runner()->PostTask(
294 FROM_HERE,
295 base::Bind(&base::WaitableEvent::Signal,
296 base::Unretained(&last_task_event)));
297
298 // Stop() is non-blocking, but Yield() to |a|, wait for last task to be
299 // processed and a little more for QuitWhenIdle() to unwind before considering
300 // the thread "stopped".
301 a.Stop();
302 base::PlatformThread::YieldCurrentThread();
303 last_task_event.Wait();
304 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
305
306 // This test assumes that the above was sufficient to let the thread fully
307 // stop.
308 ASSERT_FALSE(a.IsRunning());
309
310 // Restarting it should not be allowed.
311 EXPECT_DCHECK_DEATH(a.Start(), "");
312 }
313
234 TEST_F(ThreadTest, ThreadName) { 314 TEST_F(ThreadTest, ThreadName) {
235 Thread a("ThreadName"); 315 Thread a("ThreadName");
236 EXPECT_TRUE(a.Start()); 316 EXPECT_TRUE(a.Start());
237 EXPECT_EQ("ThreadName", a.thread_name()); 317 EXPECT_EQ("ThreadName", a.thread_name());
238 } 318 }
239 319
240 TEST_F(ThreadTest, ThreadId) { 320 TEST_F(ThreadTest, ThreadId) {
241 Thread a("ThreadId0"); 321 Thread a("ThreadId0");
242 Thread b("ThreadId1"); 322 Thread b("ThreadId1");
243 a.Start(); 323 a.Start();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 EXPECT_FALSE(a.task_runner()); 405 EXPECT_FALSE(a.task_runner());
326 } 406 }
327 407
328 TEST_F(ThreadTest, MultipleWaitUntilThreadStarted) { 408 TEST_F(ThreadTest, MultipleWaitUntilThreadStarted) {
329 Thread a("MultipleWaitUntilThreadStarted"); 409 Thread a("MultipleWaitUntilThreadStarted");
330 EXPECT_TRUE(a.Start()); 410 EXPECT_TRUE(a.Start());
331 // It's OK to call WaitUntilThreadStarted() multiple times. 411 // It's OK to call WaitUntilThreadStarted() multiple times.
332 EXPECT_TRUE(a.WaitUntilThreadStarted()); 412 EXPECT_TRUE(a.WaitUntilThreadStarted());
333 EXPECT_TRUE(a.WaitUntilThreadStarted()); 413 EXPECT_TRUE(a.WaitUntilThreadStarted());
334 } 414 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698