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

Side by Side Diff: base/task_unittest.cc

Issue 7210053: Implementation of PostTaskAndReply() in MessageLoopProxy and BrowserThread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added unittests Created 9 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 | Annotate | Revision Log
« no previous file with comments | « base/task.cc ('k') | content/browser/browser_thread.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/task.h"
6
7 #include "base/bind.h"
5 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
6 #include "base/task.h" 9 #include "base/message_loop.h"
10 #include "base/threading/thread.h"
7 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
8 12
9 namespace { 13 namespace {
10 14
11 class CancelInDestructor : public base::RefCounted<CancelInDestructor> { 15 class CancelInDestructor : public base::RefCounted<CancelInDestructor> {
12 public: 16 public:
13 CancelInDestructor() : cancelable_task_(NULL) {} 17 CancelInDestructor() : cancelable_task_(NULL) {}
14 18
15 void Start() { 19 void Start() {
16 if (cancelable_task_) { 20 if (cancelable_task_) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 EXPECT_EQ(0, run_count); 104 EXPECT_EQ(0, run_count);
101 done_task->Run(); 105 done_task->Run();
102 EXPECT_FALSE(was_deleted); 106 EXPECT_FALSE(was_deleted);
103 EXPECT_EQ(1, run_count); 107 EXPECT_EQ(1, run_count);
104 } 108 }
105 EXPECT_EQ(1, run_count); 109 EXPECT_EQ(1, run_count);
106 delete done_task; 110 delete done_task;
107 EXPECT_TRUE(was_deleted); 111 EXPECT_TRUE(was_deleted);
108 } 112 }
109 113
114 class LoopRecorder : public base::RefCountedThreadSafe<LoopRecorder> {
willchan no longer on Chromium 2011/08/17 04:36:07 I'm not sure why you make this RefCountedThreadSaf
awong 2011/08/17 05:16:00 I figured that in the case that someone introduced
115 public:
116 LoopRecorder(MessageLoop** run_on, MessageLoop** deleted_on)
117 : run_on_(run_on),
118 deleted_on_(deleted_on) {
119 }
120
121 void RecordRun() {
122 *run_on_ = MessageLoop::current();
123 }
124
125 private:
126 friend class base::RefCountedThreadSafe<LoopRecorder>;
127 ~LoopRecorder() {
128 *deleted_on_ = MessageLoop::current();
129 }
130
131 MessageLoop** run_on_;
132 MessageLoop** deleted_on_;
133 };
134
135 void RecordLoop(scoped_refptr<LoopRecorder> recorder) {
136 recorder->RecordRun();
137 }
138
139 void RecordLoopAndQuit(scoped_refptr<LoopRecorder> recorder) {
140 recorder->RecordRun();
141 MessageLoop::current()->Quit();
142 }
143
144 TEST(TaskTest, TestPostTaskAndReplyRelay_Basic) {
145 using base::internal::PostTaskAndReplyRelay;
146
147 MessageLoop current_loop;
148
149 MessageLoop* task_run_on = NULL;
150 MessageLoop* task_deleted_on = NULL;
151 MessageLoop* reply_run_on = NULL;
152 MessageLoop* reply_deleted_on = NULL;
153
154 scoped_refptr<LoopRecorder> task_recoder =
willchan no longer on Chromium 2011/08/17 04:36:07 s/task_recoder/task_recorder/?
awong 2011/08/17 05:16:00 Will fix tomorrow.
155 new LoopRecorder(&task_run_on, &task_deleted_on);
156 scoped_refptr<LoopRecorder> reply_recoder =
157 new LoopRecorder(&reply_run_on, &reply_deleted_on);
158
159 PostTaskAndReplyRelay* relay =
160 new PostTaskAndReplyRelay(
161 FROM_HERE,
162 base::Bind(&RecordLoop, task_recoder),
163 base::Bind(&RecordLoopAndQuit, reply_recoder));
164
165 // Die if base::Bind doesn't retain a reference to the recorders.
166 task_recoder = NULL;
167 reply_recoder = NULL;
168 ASSERT_FALSE(task_deleted_on);
169 ASSERT_FALSE(reply_deleted_on);
170
171 // Run the relay.
172 base::Thread task_thread("task_thread");
173 task_thread.Start();
174 task_thread.message_loop()->PostTask(
175 FROM_HERE,
176 base::Bind(&PostTaskAndReplyRelay::Run, base::Unretained(relay)));
177
178 current_loop.Run();
179
180 EXPECT_EQ(task_thread.message_loop(), task_run_on);
181 EXPECT_EQ(&current_loop, task_deleted_on);
182 EXPECT_EQ(&current_loop, reply_run_on);
183 EXPECT_EQ(&current_loop, reply_deleted_on);
184 }
185
186 TEST(TaskTest, TestPostTaskAndReplyRelay_SameLoop) {
187 using base::internal::PostTaskAndReplyRelay;
188
189 MessageLoop current_loop;
190
191 MessageLoop* task_run_on = NULL;
192 MessageLoop* task_deleted_on = NULL;
193 MessageLoop* reply_run_on = NULL;
194 MessageLoop* reply_deleted_on = NULL;
195
196 scoped_refptr<LoopRecorder> task_recoder =
197 new LoopRecorder(&task_run_on, &task_deleted_on);
198 scoped_refptr<LoopRecorder> reply_recoder =
199 new LoopRecorder(&reply_run_on, &reply_deleted_on);
200
201 PostTaskAndReplyRelay* relay =
202 new PostTaskAndReplyRelay(
203 FROM_HERE,
204 base::Bind(&RecordLoop, task_recoder),
205 base::Bind(&RecordLoopAndQuit, reply_recoder));
206
207 // Die if base::Bind doesn't retain a reference to the recorders.
208 task_recoder = NULL;
209 reply_recoder = NULL;
210 ASSERT_FALSE(task_deleted_on);
211 ASSERT_FALSE(reply_deleted_on);
212
213 // Run the relay.
214 current_loop.PostTask(
215 FROM_HERE,
216 base::Bind(&PostTaskAndReplyRelay::Run, base::Unretained(relay)));
217
218 current_loop.Run();
219
220 EXPECT_EQ(&current_loop, task_run_on);
221 EXPECT_EQ(&current_loop, task_deleted_on);
222 EXPECT_EQ(&current_loop, reply_run_on);
223 EXPECT_EQ(&current_loop, reply_deleted_on);
224 }
225
226 TEST(TaskTest, TestPostTaskAndReplyRelay_DeadReplyLoopDoesNotDelete) {
227 using base::internal::PostTaskAndReplyRelay;
228
229 scoped_ptr<MessageLoop> current_loop(new MessageLoop());
230
231 MessageLoop* task_run_on = NULL;
232 MessageLoop* task_deleted_on = NULL;
233 MessageLoop* reply_run_on = NULL;
234 MessageLoop* reply_deleted_on = NULL;
235
236 scoped_refptr<LoopRecorder> task_recoder =
237 new LoopRecorder(&task_run_on, &task_deleted_on);
238 scoped_refptr<LoopRecorder> reply_recoder =
239 new LoopRecorder(&reply_run_on, &reply_deleted_on);
240
241 PostTaskAndReplyRelay* relay =
242 new PostTaskAndReplyRelay(
243 FROM_HERE,
244 base::Bind(&RecordLoop, task_recoder),
245 base::Bind(&RecordLoopAndQuit, reply_recoder));
246
247 // Die if base::Bind doesn't retain a reference to the recorders.
248 task_recoder = NULL;
249 reply_recoder = NULL;
250 ASSERT_FALSE(task_deleted_on);
251 ASSERT_FALSE(reply_deleted_on);
252
253 // Run the relay.
254 base::Thread task_thread("task_thread");
255 task_thread.Start();
256 task_thread.message_loop()->PostTask(
257 FROM_HERE,
258 base::Bind(&PostTaskAndReplyRelay::Run, base::Unretained(relay)));
259
260 // Mercilessly whack the current loop before |reply| gets to run.
261 current_loop.reset();
262
263 // This should ensure the relay has been run. We need to record the
264 // MessageLoop pointer before stopping the thread because Thread::Stop() will
265 // NULL out its own pointer.
266 MessageLoop* task_loop = task_thread.message_loop();
267 task_thread.Stop();
268
269 EXPECT_EQ(task_loop, task_run_on);
270 ASSERT_FALSE(task_deleted_on);
271 EXPECT_FALSE(reply_run_on);
272 ASSERT_FALSE(reply_deleted_on);
273
274 // Relay is leaked here.
275 // TODO(ajwong): Is there a way to make Valgrind not hate us?
willchan no longer on Chromium 2011/08/17 04:36:07 delete relay; :)
awong 2011/08/17 05:16:00 Tried that. Dies cause the Relay asserts that it i
276 }
277
110 } // namespace 278 } // namespace
OLDNEW
« no previous file with comments | « base/task.cc ('k') | content/browser/browser_thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698