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

Side by Side Diff: base/message_loop/message_loop_task_runner_unittest.cc

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 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/message_loop/message_loop_proxy.h" 5 #include "base/message_loop/message_loop_task_runner.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/debug/leak_annotations.h" 9 #include "base/debug/leak_annotations.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/message_loop/message_loop_task_runner.h"
13 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
14 #include "base/thread_task_runner_handle.h"
14 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/platform_test.h"
16 18
17 namespace base { 19 namespace base {
18 20
19 namespace { 21 class MessageLoopTaskRunnerTest : public testing::Test {
20
21 class MessageLoopProxyTest : public testing::Test {
22 public: 22 public:
23 MessageLoopProxyTest() 23 MessageLoopTaskRunnerTest()
24 : current_loop_(new MessageLoop()), 24 : current_loop_(new MessageLoop()),
25 task_thread_("task_thread"), 25 task_thread_("task_thread"),
26 thread_sync_(true, false) { 26 thread_sync_(true, false) {}
27 }
28 27
29 void DeleteCurrentMessageLoop() { 28 void DeleteCurrentMessageLoop() { current_loop_.reset(); }
30 current_loop_.reset();
31 }
32 29
33 protected: 30 protected:
34 void SetUp() override { 31 void SetUp() override {
35 // Use SetUp() instead of the constructor to avoid posting a task to a 32 // Use SetUp() instead of the constructor to avoid posting a task to a
36 // partialy constructed object. 33 // partialy constructed object.
37 task_thread_.Start(); 34 task_thread_.Start();
38 35
39 // Allow us to pause the |task_thread_|'s MessageLoop. 36 // Allow us to pause the |task_thread_|'s MessageLoop.
40 task_thread_.message_loop()->PostTask( 37 task_thread_.message_loop()->PostTask(
41 FROM_HERE, 38 FROM_HERE, Bind(&MessageLoopTaskRunnerTest::BlockTaskThreadHelper,
42 Bind(&MessageLoopProxyTest::BlockTaskThreadHelper, Unretained(this))); 39 Unretained(this)));
43 } 40 }
44 41
45 void TearDown() override { 42 void TearDown() override {
46 // Make sure the |task_thread_| is not blocked, and stop the thread 43 // Make sure the |task_thread_| is not blocked, and stop the thread
47 // fully before destuction because its tasks may still depend on the 44 // fully before destuction because its tasks may still depend on the
48 // |thread_sync_| event. 45 // |thread_sync_| event.
49 thread_sync_.Signal(); 46 thread_sync_.Signal();
50 task_thread_.Stop(); 47 task_thread_.Stop();
51 DeleteCurrentMessageLoop(); 48 DeleteCurrentMessageLoop();
52 } 49 }
53 50
54 // Make LoopRecorder threadsafe so that there is defined behavior even if a 51 // Make LoopRecorder threadsafe so that there is defined behavior even if a
55 // threading mistake sneaks into the PostTaskAndReplyRelay implementation. 52 // threading mistake sneaks into the PostTaskAndReplyRelay implementation.
56 class LoopRecorder : public RefCountedThreadSafe<LoopRecorder> { 53 class LoopRecorder : public RefCountedThreadSafe<LoopRecorder> {
57 public: 54 public:
58 LoopRecorder(MessageLoop** run_on, MessageLoop** deleted_on, 55 LoopRecorder(MessageLoop** run_on,
56 MessageLoop** deleted_on,
59 int* destruct_order) 57 int* destruct_order)
60 : run_on_(run_on), 58 : run_on_(run_on),
61 deleted_on_(deleted_on), 59 deleted_on_(deleted_on),
62 destruct_order_(destruct_order) { 60 destruct_order_(destruct_order) {}
63 }
64 61
65 void RecordRun() { 62 void RecordRun() { *run_on_ = MessageLoop::current(); }
66 *run_on_ = MessageLoop::current();
67 }
68 63
69 private: 64 private:
70 friend class RefCountedThreadSafe<LoopRecorder>; 65 friend class RefCountedThreadSafe<LoopRecorder>;
71 ~LoopRecorder() { 66 ~LoopRecorder() {
72 *deleted_on_ = MessageLoop::current(); 67 *deleted_on_ = MessageLoop::current();
73 *destruct_order_ = g_order.GetNext(); 68 *destruct_order_ = g_order.GetNext();
74 } 69 }
75 70
76 MessageLoop** run_on_; 71 MessageLoop** run_on_;
77 MessageLoop** deleted_on_; 72 MessageLoop** deleted_on_;
78 int* destruct_order_; 73 int* destruct_order_;
79 }; 74 };
80 75
81 static void RecordLoop(scoped_refptr<LoopRecorder> recorder) { 76 static void RecordLoop(scoped_refptr<LoopRecorder> recorder) {
82 recorder->RecordRun(); 77 recorder->RecordRun();
83 } 78 }
84 79
85 static void RecordLoopAndQuit(scoped_refptr<LoopRecorder> recorder) { 80 static void RecordLoopAndQuit(scoped_refptr<LoopRecorder> recorder) {
86 recorder->RecordRun(); 81 recorder->RecordRun();
87 MessageLoop::current()->QuitWhenIdle(); 82 MessageLoop::current()->QuitWhenIdle();
88 } 83 }
89 84
90 void UnblockTaskThread() { 85 void UnblockTaskThread() { thread_sync_.Signal(); }
91 thread_sync_.Signal();
92 }
93 86
94 void BlockTaskThreadHelper() { 87 void BlockTaskThreadHelper() { thread_sync_.Wait(); }
95 thread_sync_.Wait();
96 }
97 88
98 static StaticAtomicSequenceNumber g_order; 89 static StaticAtomicSequenceNumber g_order;
99 90
100 scoped_ptr<MessageLoop> current_loop_; 91 scoped_ptr<MessageLoop> current_loop_;
101 Thread task_thread_; 92 Thread task_thread_;
102 93
103 private: 94 private:
104 base::WaitableEvent thread_sync_; 95 base::WaitableEvent thread_sync_;
105 }; 96 };
106 97
107 StaticAtomicSequenceNumber MessageLoopProxyTest::g_order; 98 StaticAtomicSequenceNumber MessageLoopTaskRunnerTest::g_order;
108 99
109 TEST_F(MessageLoopProxyTest, PostTaskAndReply_Basic) { 100 TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReply_Basic) {
110 MessageLoop* task_run_on = NULL; 101 MessageLoop* task_run_on = NULL;
111 MessageLoop* task_deleted_on = NULL; 102 MessageLoop* task_deleted_on = NULL;
112 int task_delete_order = -1; 103 int task_delete_order = -1;
113 MessageLoop* reply_run_on = NULL; 104 MessageLoop* reply_run_on = NULL;
114 MessageLoop* reply_deleted_on = NULL; 105 MessageLoop* reply_deleted_on = NULL;
115 int reply_delete_order = -1; 106 int reply_delete_order = -1;
116 107
117 scoped_refptr<LoopRecorder> task_recoder = 108 scoped_refptr<LoopRecorder> task_recoder =
118 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); 109 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
119 scoped_refptr<LoopRecorder> reply_recoder = 110 scoped_refptr<LoopRecorder> reply_recoder =
120 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); 111 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
121 112
122 ASSERT_TRUE(task_thread_.message_loop_proxy()->PostTaskAndReply( 113 ASSERT_TRUE(task_thread_.task_runner()->PostTaskAndReply(
123 FROM_HERE, 114 FROM_HERE, Bind(&RecordLoop, task_recoder),
124 Bind(&RecordLoop, task_recoder),
125 Bind(&RecordLoopAndQuit, reply_recoder))); 115 Bind(&RecordLoopAndQuit, reply_recoder)));
126 116
127 // Die if base::Bind doesn't retain a reference to the recorders. 117 // Die if base::Bind doesn't retain a reference to the recorders.
128 task_recoder = NULL; 118 task_recoder = NULL;
129 reply_recoder = NULL; 119 reply_recoder = NULL;
130 ASSERT_FALSE(task_deleted_on); 120 ASSERT_FALSE(task_deleted_on);
131 ASSERT_FALSE(reply_deleted_on); 121 ASSERT_FALSE(reply_deleted_on);
132 122
133 UnblockTaskThread(); 123 UnblockTaskThread();
134 current_loop_->Run(); 124 current_loop_->Run();
135 125
136 EXPECT_EQ(task_thread_.message_loop(), task_run_on); 126 EXPECT_EQ(task_thread_.message_loop(), task_run_on);
137 EXPECT_EQ(current_loop_.get(), task_deleted_on); 127 EXPECT_EQ(current_loop_.get(), task_deleted_on);
138 EXPECT_EQ(current_loop_.get(), reply_run_on); 128 EXPECT_EQ(current_loop_.get(), reply_run_on);
139 EXPECT_EQ(current_loop_.get(), reply_deleted_on); 129 EXPECT_EQ(current_loop_.get(), reply_deleted_on);
140 EXPECT_LT(task_delete_order, reply_delete_order); 130 EXPECT_LT(task_delete_order, reply_delete_order);
141 } 131 }
142 132
143 TEST_F(MessageLoopProxyTest, PostTaskAndReplyOnDeletedThreadDoesNotLeak) { 133 TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReplyOnDeletedThreadDoesNotLeak) {
144 MessageLoop* task_run_on = NULL; 134 MessageLoop* task_run_on = NULL;
145 MessageLoop* task_deleted_on = NULL; 135 MessageLoop* task_deleted_on = NULL;
146 int task_delete_order = -1; 136 int task_delete_order = -1;
147 MessageLoop* reply_run_on = NULL; 137 MessageLoop* reply_run_on = NULL;
148 MessageLoop* reply_deleted_on = NULL; 138 MessageLoop* reply_deleted_on = NULL;
149 int reply_delete_order = -1; 139 int reply_delete_order = -1;
150 140
151 scoped_refptr<LoopRecorder> task_recoder = 141 scoped_refptr<LoopRecorder> task_recoder =
152 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); 142 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
153 scoped_refptr<LoopRecorder> reply_recoder = 143 scoped_refptr<LoopRecorder> reply_recoder =
154 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); 144 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
155 145
156 // Grab a MessageLoopProxy to a dead MessageLoop. 146 // Grab a task runner to a dead MessageLoop.
157 scoped_refptr<MessageLoopProxy> task_loop_proxy = 147 scoped_refptr<SingleThreadTaskRunner> task_runner =
158 task_thread_.message_loop_proxy(); 148 task_thread_.task_runner();
159 UnblockTaskThread(); 149 UnblockTaskThread();
160 task_thread_.Stop(); 150 task_thread_.Stop();
161 151
162 ASSERT_FALSE(task_loop_proxy->PostTaskAndReply( 152 ASSERT_FALSE(
163 FROM_HERE, 153 task_runner->PostTaskAndReply(FROM_HERE, Bind(&RecordLoop, task_recoder),
164 Bind(&RecordLoop, task_recoder), 154 Bind(&RecordLoopAndQuit, reply_recoder)));
165 Bind(&RecordLoopAndQuit, reply_recoder)));
166 155
167 // The relay should have properly deleted its resources leaving us as the only 156 // The relay should have properly deleted its resources leaving us as the only
168 // reference. 157 // reference.
169 EXPECT_EQ(task_delete_order, reply_delete_order); 158 EXPECT_EQ(task_delete_order, reply_delete_order);
170 ASSERT_TRUE(task_recoder->HasOneRef()); 159 ASSERT_TRUE(task_recoder->HasOneRef());
171 ASSERT_TRUE(reply_recoder->HasOneRef()); 160 ASSERT_TRUE(reply_recoder->HasOneRef());
172 161
173 // Nothing should have run though. 162 // Nothing should have run though.
174 EXPECT_FALSE(task_run_on); 163 EXPECT_FALSE(task_run_on);
175 EXPECT_FALSE(reply_run_on); 164 EXPECT_FALSE(reply_run_on);
176 } 165 }
177 166
178 TEST_F(MessageLoopProxyTest, PostTaskAndReply_SameLoop) { 167 TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReply_SameLoop) {
179 MessageLoop* task_run_on = NULL; 168 MessageLoop* task_run_on = NULL;
180 MessageLoop* task_deleted_on = NULL; 169 MessageLoop* task_deleted_on = NULL;
181 int task_delete_order = -1; 170 int task_delete_order = -1;
182 MessageLoop* reply_run_on = NULL; 171 MessageLoop* reply_run_on = NULL;
183 MessageLoop* reply_deleted_on = NULL; 172 MessageLoop* reply_deleted_on = NULL;
184 int reply_delete_order = -1; 173 int reply_delete_order = -1;
185 174
186 scoped_refptr<LoopRecorder> task_recoder = 175 scoped_refptr<LoopRecorder> task_recoder =
187 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); 176 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
188 scoped_refptr<LoopRecorder> reply_recoder = 177 scoped_refptr<LoopRecorder> reply_recoder =
189 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); 178 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
190 179
191 // Enqueue the relay. 180 // Enqueue the relay.
192 ASSERT_TRUE(current_loop_->message_loop_proxy()->PostTaskAndReply( 181 ASSERT_TRUE(current_loop_->task_runner()->PostTaskAndReply(
193 FROM_HERE, 182 FROM_HERE, Bind(&RecordLoop, task_recoder),
194 Bind(&RecordLoop, task_recoder),
195 Bind(&RecordLoopAndQuit, reply_recoder))); 183 Bind(&RecordLoopAndQuit, reply_recoder)));
196 184
197 // Die if base::Bind doesn't retain a reference to the recorders. 185 // Die if base::Bind doesn't retain a reference to the recorders.
198 task_recoder = NULL; 186 task_recoder = NULL;
199 reply_recoder = NULL; 187 reply_recoder = NULL;
200 ASSERT_FALSE(task_deleted_on); 188 ASSERT_FALSE(task_deleted_on);
201 ASSERT_FALSE(reply_deleted_on); 189 ASSERT_FALSE(reply_deleted_on);
202 190
203 current_loop_->Run(); 191 current_loop_->Run();
204 192
205 EXPECT_EQ(current_loop_.get(), task_run_on); 193 EXPECT_EQ(current_loop_.get(), task_run_on);
206 EXPECT_EQ(current_loop_.get(), task_deleted_on); 194 EXPECT_EQ(current_loop_.get(), task_deleted_on);
207 EXPECT_EQ(current_loop_.get(), reply_run_on); 195 EXPECT_EQ(current_loop_.get(), reply_run_on);
208 EXPECT_EQ(current_loop_.get(), reply_deleted_on); 196 EXPECT_EQ(current_loop_.get(), reply_deleted_on);
209 EXPECT_LT(task_delete_order, reply_delete_order); 197 EXPECT_LT(task_delete_order, reply_delete_order);
210 } 198 }
211 199
212 TEST_F(MessageLoopProxyTest, PostTaskAndReply_DeadReplyLoopDoesNotDelete) { 200 TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReply_DeadReplyLoopDoesNotDelete) {
213 // Annotate the scope as having memory leaks to suppress heapchecker reports. 201 // Annotate the scope as having memory leaks to suppress heapchecker reports.
214 ANNOTATE_SCOPED_MEMORY_LEAK; 202 ANNOTATE_SCOPED_MEMORY_LEAK;
215 MessageLoop* task_run_on = NULL; 203 MessageLoop* task_run_on = NULL;
216 MessageLoop* task_deleted_on = NULL; 204 MessageLoop* task_deleted_on = NULL;
217 int task_delete_order = -1; 205 int task_delete_order = -1;
218 MessageLoop* reply_run_on = NULL; 206 MessageLoop* reply_run_on = NULL;
219 MessageLoop* reply_deleted_on = NULL; 207 MessageLoop* reply_deleted_on = NULL;
220 int reply_delete_order = -1; 208 int reply_delete_order = -1;
221 209
222 scoped_refptr<LoopRecorder> task_recoder = 210 scoped_refptr<LoopRecorder> task_recoder =
223 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order); 211 new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
224 scoped_refptr<LoopRecorder> reply_recoder = 212 scoped_refptr<LoopRecorder> reply_recoder =
225 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order); 213 new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
226 214
227 // Enqueue the relay. 215 // Enqueue the relay.
228 task_thread_.message_loop_proxy()->PostTaskAndReply( 216 task_thread_.task_runner()->PostTaskAndReply(
229 FROM_HERE, 217 FROM_HERE, Bind(&RecordLoop, task_recoder),
230 Bind(&RecordLoop, task_recoder),
231 Bind(&RecordLoopAndQuit, reply_recoder)); 218 Bind(&RecordLoopAndQuit, reply_recoder));
232 219
233 // Die if base::Bind doesn't retain a reference to the recorders. 220 // Die if base::Bind doesn't retain a reference to the recorders.
234 task_recoder = NULL; 221 task_recoder = NULL;
235 reply_recoder = NULL; 222 reply_recoder = NULL;
236 ASSERT_FALSE(task_deleted_on); 223 ASSERT_FALSE(task_deleted_on);
237 ASSERT_FALSE(reply_deleted_on); 224 ASSERT_FALSE(reply_deleted_on);
238 225
239 UnblockTaskThread(); 226 UnblockTaskThread();
240 227
(...skipping 13 matching lines...) Expand all
254 EXPECT_EQ(task_delete_order, reply_delete_order); 241 EXPECT_EQ(task_delete_order, reply_delete_order);
255 242
256 // The PostTaskAndReplyRelay is leaked here. Even if we had a reference to 243 // The PostTaskAndReplyRelay is leaked here. Even if we had a reference to
257 // it, we cannot just delete it because PostTaskAndReplyRelay's destructor 244 // it, we cannot just delete it because PostTaskAndReplyRelay's destructor
258 // checks that MessageLoop::current() is the the same as when the 245 // checks that MessageLoop::current() is the the same as when the
259 // PostTaskAndReplyRelay object was constructed. However, this loop must have 246 // PostTaskAndReplyRelay object was constructed. However, this loop must have
260 // aleady been deleted in order to perform this test. See 247 // aleady been deleted in order to perform this test. See
261 // http://crbug.com/86301. 248 // http://crbug.com/86301.
262 } 249 }
263 250
264 } // namespace 251 class MessageLoopTaskRunnerThreadingTest : public testing::Test {
252 public:
253 void Release() const {
254 AssertOnIOThread();
255 Quit();
256 }
257
258 void Quit() const {
259 loop_.PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
260 }
261
262 void AssertOnIOThread() const {
263 ASSERT_TRUE(io_thread_->task_runner()->BelongsToCurrentThread());
264 ASSERT_EQ(io_thread_->task_runner(), ThreadTaskRunnerHandle::Get());
265 }
266
267 void AssertOnFileThread() const {
268 ASSERT_TRUE(file_thread_->task_runner()->BelongsToCurrentThread());
269 ASSERT_EQ(file_thread_->task_runner(), ThreadTaskRunnerHandle::Get());
270 }
271
272 protected:
273 void SetUp() override {
274 io_thread_.reset(new Thread("MessageLoopTaskRunnerThreadingTest_IO"));
275 file_thread_.reset(new Thread("MessageLoopTaskRunnerThreadingTest_File"));
276 io_thread_->Start();
277 file_thread_->Start();
278 }
279
280 void TearDown() override {
281 io_thread_->Stop();
282 file_thread_->Stop();
283 }
284
285 static void BasicFunction(MessageLoopTaskRunnerThreadingTest* test) {
286 test->AssertOnFileThread();
287 test->Quit();
288 }
289
290 static void AssertNotRun() { FAIL() << "Callback Should not get executed."; }
291
292 class DeletedOnFile {
293 public:
294 explicit DeletedOnFile(MessageLoopTaskRunnerThreadingTest* test)
295 : test_(test) {}
296
297 ~DeletedOnFile() {
298 test_->AssertOnFileThread();
299 test_->Quit();
300 }
301
302 private:
303 MessageLoopTaskRunnerThreadingTest* test_;
304 };
305
306 scoped_ptr<Thread> io_thread_;
307 scoped_ptr<Thread> file_thread_;
308
309 private:
310 mutable MessageLoop loop_;
311 };
312
313 TEST_F(MessageLoopTaskRunnerThreadingTest, Release) {
314 EXPECT_TRUE(io_thread_->task_runner()->ReleaseSoon(FROM_HERE, this));
315 MessageLoop::current()->Run();
316 }
317
318 TEST_F(MessageLoopTaskRunnerThreadingTest, Delete) {
319 DeletedOnFile* deleted_on_file = new DeletedOnFile(this);
320 EXPECT_TRUE(
321 file_thread_->task_runner()->DeleteSoon(FROM_HERE, deleted_on_file));
322 MessageLoop::current()->Run();
323 }
324
325 TEST_F(MessageLoopTaskRunnerThreadingTest, PostTask) {
326 EXPECT_TRUE(file_thread_->task_runner()->PostTask(
327 FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::BasicFunction,
328 Unretained(this))));
329 MessageLoop::current()->Run();
330 }
331
332 TEST_F(MessageLoopTaskRunnerThreadingTest, PostTaskAfterThreadExits) {
333 scoped_ptr<Thread> test_thread(
334 new Thread("MessageLoopTaskRunnerThreadingTest_Dummy"));
335 test_thread->Start();
336 scoped_refptr<SingleThreadTaskRunner> task_runner =
337 test_thread->task_runner();
338 test_thread->Stop();
339
340 bool ret = task_runner->PostTask(
341 FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::AssertNotRun));
342 EXPECT_FALSE(ret);
343 }
344
345 TEST_F(MessageLoopTaskRunnerThreadingTest, PostTaskAfterThreadIsDeleted) {
346 scoped_refptr<SingleThreadTaskRunner> task_runner;
347 {
348 scoped_ptr<Thread> test_thread(
349 new Thread("MessageLoopTaskRunnerThreadingTest_Dummy"));
350 test_thread->Start();
351 task_runner = test_thread->task_runner();
352 }
353 bool ret = task_runner->PostTask(
354 FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::AssertNotRun));
355 EXPECT_FALSE(ret);
356 }
265 357
266 } // namespace base 358 } // namespace base
OLDNEW
« no previous file with comments | « base/message_loop/message_loop_task_runner.cc ('k') | base/message_loop/message_loop_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698