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

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

Issue 2824533002: Migrate Bind to BindOnce or BindRepeating in //base/message_loop (Closed)
Patch Set: Created 3 years, 8 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_pump_glib.h" 5 #include "base/message_loop/message_pump_glib.h"
6 6
7 #include <glib.h> 7 #include <glib.h>
8 #include <math.h> 8 #include <math.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 bool HandleCheck() { 53 bool HandleCheck() {
54 if (events_.empty()) 54 if (events_.empty())
55 return false; 55 return false;
56 return events_[0].time <= Time::NowFromSystemTime(); 56 return events_[0].time <= Time::NowFromSystemTime();
57 } 57 }
58 58
59 void HandleDispatch() { 59 void HandleDispatch() {
60 if (events_.empty()) 60 if (events_.empty())
61 return; 61 return;
62 Event event = events_[0]; 62 Event event = std::move(events_[0]);
63 events_.erase(events_.begin()); 63 events_.erase(events_.begin());
64 ++processed_events_; 64 ++processed_events_;
65 if (!event.callback.is_null()) 65 if (!event.callback.is_null())
66 event.callback.Run(); 66 std::move(event.callback).Run();
67 else if (!event.task.is_null()) 67 else if (!event.task.is_null())
68 event.task.Run(); 68 std::move(event.task).Run();
69 } 69 }
70 70
71 // Adds an event to the queue. When "handled", executes |callback|. 71 // Adds an event to the queue. When "handled", executes |callback|.
72 // delay_ms is relative to the last event if any, or to Now() otherwise. 72 // delay_ms is relative to the last event if any, or to Now() otherwise.
73 void AddEvent(int delay_ms, const Closure& callback) { 73 void AddEvent(int delay_ms, OnceClosure callback) {
74 AddEventHelper(delay_ms, callback, Closure()); 74 AddEventHelper(delay_ms, std::move(callback), OnceClosure());
75 } 75 }
76 76
77 void AddDummyEvent(int delay_ms) { 77 void AddDummyEvent(int delay_ms) {
78 AddEventHelper(delay_ms, Closure(), Closure()); 78 AddEventHelper(delay_ms, OnceClosure(), OnceClosure());
79 } 79 }
80 80
81 void AddEventAsTask(int delay_ms, const Closure& task) { 81 void AddEventAsTask(int delay_ms, OnceClosure task) {
82 AddEventHelper(delay_ms, Closure(), task); 82 AddEventHelper(delay_ms, OnceClosure(), std::move(task));
83 } 83 }
84 84
85 void Reset() { 85 void Reset() {
86 processed_events_ = 0; 86 processed_events_ = 0;
87 events_.clear(); 87 events_.clear();
88 } 88 }
89 89
90 int processed_events() const { return processed_events_; } 90 int processed_events() const { return processed_events_; }
91 91
92 private: 92 private:
93 struct Event { 93 struct Event {
94 Time time; 94 Time time;
95 Closure callback; 95 OnceClosure callback;
96 Closure task; 96 OnceClosure task;
97 }; 97 };
98 98
99 struct Source : public GSource { 99 struct Source : public GSource {
100 EventInjector* injector; 100 EventInjector* injector;
101 }; 101 };
102 102
103 void AddEventHelper( 103 void AddEventHelper(int delay_ms, OnceClosure callback, OnceClosure task) {
104 int delay_ms, const Closure& callback, const Closure& task) {
105 Time last_time; 104 Time last_time;
106 if (!events_.empty()) 105 if (!events_.empty())
107 last_time = (events_.end()-1)->time; 106 last_time = (events_.end()-1)->time;
108 else 107 else
109 last_time = Time::NowFromSystemTime(); 108 last_time = Time::NowFromSystemTime();
110 109
111 Time future = last_time + TimeDelta::FromMilliseconds(delay_ms); 110 Time future = last_time + TimeDelta::FromMilliseconds(delay_ms);
112 EventInjector::Event event = {future, callback, task}; 111 EventInjector::Event event = {future, std::move(callback), std::move(task)};
113 events_.push_back(event); 112 events_.push_back(std::move(event));
114 } 113 }
115 114
116 static gboolean Prepare(GSource* source, gint* timeout_ms) { 115 static gboolean Prepare(GSource* source, gint* timeout_ms) {
117 *timeout_ms = static_cast<Source*>(source)->injector->HandlePrepare(); 116 *timeout_ms = static_cast<Source*>(source)->injector->HandlePrepare();
118 return FALSE; 117 return FALSE;
119 } 118 }
120 119
121 static gboolean Check(GSource* source) { 120 static gboolean Check(GSource* source) {
122 return static_cast<Source*>(source)->injector->HandleCheck(); 121 return static_cast<Source*>(source)->injector->HandleCheck();
123 } 122 }
(...skipping 23 matching lines...) Expand all
147 ++*value; 146 ++*value;
148 } 147 }
149 148
150 // Checks how many events have been processed by the injector. 149 // Checks how many events have been processed by the injector.
151 void ExpectProcessedEvents(EventInjector* injector, int count) { 150 void ExpectProcessedEvents(EventInjector* injector, int count) {
152 EXPECT_EQ(injector->processed_events(), count); 151 EXPECT_EQ(injector->processed_events(), count);
153 } 152 }
154 153
155 // Posts a task on the current message loop. 154 // Posts a task on the current message loop.
156 void PostMessageLoopTask(const tracked_objects::Location& from_here, 155 void PostMessageLoopTask(const tracked_objects::Location& from_here,
157 const Closure& task) { 156 OnceClosure task) {
158 ThreadTaskRunnerHandle::Get()->PostTask(from_here, task); 157 ThreadTaskRunnerHandle::Get()->PostTask(from_here, std::move(task));
159 } 158 }
160 159
161 // Test fixture. 160 // Test fixture.
162 class MessagePumpGLibTest : public testing::Test { 161 class MessagePumpGLibTest : public testing::Test {
163 public: 162 public:
164 MessagePumpGLibTest() : loop_(NULL), injector_(NULL) { } 163 MessagePumpGLibTest() : loop_(NULL), injector_(NULL) { }
165 164
166 // Overridden from testing::Test: 165 // Overridden from testing::Test:
167 void SetUp() override { 166 void SetUp() override {
168 loop_ = new MessageLoop(MessageLoop::TYPE_UI); 167 loop_ = new MessageLoop(MessageLoop::TYPE_UI);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 } 200 }
202 201
203 TEST_F(MessagePumpGLibTest, TestEventTaskInterleave) { 202 TEST_F(MessagePumpGLibTest, TestEventTaskInterleave) {
204 // Checks that tasks posted by events are executed before the next event if 203 // Checks that tasks posted by events are executed before the next event if
205 // the posted task queue is empty. 204 // the posted task queue is empty.
206 // MessageLoop doesn't make strong guarantees that it is the case, but the 205 // MessageLoop doesn't make strong guarantees that it is the case, but the
207 // current implementation ensures it and the tests below rely on it. 206 // current implementation ensures it and the tests below rely on it.
208 // If changes cause this test to fail, it is reasonable to change it, but 207 // If changes cause this test to fail, it is reasonable to change it, but
209 // TestWorkWhileWaitingForEvents and TestEventsWhileWaitingForWork have to be 208 // TestWorkWhileWaitingForEvents and TestEventsWhileWaitingForWork have to be
210 // changed accordingly, otherwise they can become flaky. 209 // changed accordingly, otherwise they can become flaky.
211 injector()->AddEventAsTask(0, Bind(&DoNothing)); 210 injector()->AddEventAsTask(0, BindOnce(&DoNothing));
212 Closure check_task = 211 OnceClosure check_task =
213 Bind(&ExpectProcessedEvents, Unretained(injector()), 2); 212 BindOnce(&ExpectProcessedEvents, Unretained(injector()), 2);
214 Closure posted_task = 213 OnceClosure posted_task =
215 Bind(&PostMessageLoopTask, FROM_HERE, check_task); 214 BindOnce(&PostMessageLoopTask, FROM_HERE, std::move(check_task));
216 injector()->AddEventAsTask(0, posted_task); 215 injector()->AddEventAsTask(0, std::move(posted_task));
217 injector()->AddEventAsTask(0, Bind(&DoNothing)); 216 injector()->AddEventAsTask(0, BindOnce(&DoNothing));
218 injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure()); 217 injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
219 RunLoop().Run(); 218 RunLoop().Run();
220 EXPECT_EQ(4, injector()->processed_events()); 219 EXPECT_EQ(4, injector()->processed_events());
221 220
222 injector()->Reset(); 221 injector()->Reset();
223 injector()->AddEventAsTask(0, Bind(&DoNothing)); 222 injector()->AddEventAsTask(0, BindOnce(&DoNothing));
224 check_task = 223 check_task = BindOnce(&ExpectProcessedEvents, Unretained(injector()), 2);
225 Bind(&ExpectProcessedEvents, Unretained(injector()), 2); 224 posted_task =
226 posted_task = Bind(&PostMessageLoopTask, FROM_HERE, check_task); 225 BindOnce(&PostMessageLoopTask, FROM_HERE, std::move(check_task));
227 injector()->AddEventAsTask(0, posted_task); 226 injector()->AddEventAsTask(0, std::move(posted_task));
228 injector()->AddEventAsTask(10, Bind(&DoNothing)); 227 injector()->AddEventAsTask(10, BindOnce(&DoNothing));
229 injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure()); 228 injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
230 RunLoop().Run(); 229 RunLoop().Run();
231 EXPECT_EQ(4, injector()->processed_events()); 230 EXPECT_EQ(4, injector()->processed_events());
232 } 231 }
233 232
234 TEST_F(MessagePumpGLibTest, TestWorkWhileWaitingForEvents) { 233 TEST_F(MessagePumpGLibTest, TestWorkWhileWaitingForEvents) {
235 int task_count = 0; 234 int task_count = 0;
236 // Tests that we process tasks while waiting for new events. 235 // Tests that we process tasks while waiting for new events.
237 // The event queue is empty at first. 236 // The event queue is empty at first.
238 for (int i = 0; i < 10; ++i) { 237 for (int i = 0; i < 10; ++i) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 271
273 TEST_F(MessagePumpGLibTest, TestEventsWhileWaitingForWork) { 272 TEST_F(MessagePumpGLibTest, TestEventsWhileWaitingForWork) {
274 // Tests that we process events while waiting for work. 273 // Tests that we process events while waiting for work.
275 // The event queue is empty at first. 274 // The event queue is empty at first.
276 for (int i = 0; i < 10; ++i) { 275 for (int i = 0; i < 10; ++i) {
277 injector()->AddDummyEvent(0); 276 injector()->AddDummyEvent(0);
278 } 277 }
279 // After all the events have been processed, post a task that will check that 278 // After all the events have been processed, post a task that will check that
280 // the events have been processed (note: the task executes after the event 279 // the events have been processed (note: the task executes after the event
281 // that posted it has been handled, so we expect 11 at that point). 280 // that posted it has been handled, so we expect 11 at that point).
282 Closure check_task = 281 OnceClosure check_task =
283 Bind(&ExpectProcessedEvents, Unretained(injector()), 11); 282 BindOnce(&ExpectProcessedEvents, Unretained(injector()), 11);
284 Closure posted_task = 283 OnceClosure posted_task =
285 Bind(&PostMessageLoopTask, FROM_HERE, check_task); 284 BindOnce(&PostMessageLoopTask, FROM_HERE, std::move(check_task));
286 injector()->AddEventAsTask(10, posted_task); 285 injector()->AddEventAsTask(10, std::move(posted_task));
287 286
288 // And then quit (relies on the condition tested by TestEventTaskInterleave). 287 // And then quit (relies on the condition tested by TestEventTaskInterleave).
289 injector()->AddEvent(10, MessageLoop::QuitWhenIdleClosure()); 288 injector()->AddEvent(10, MessageLoop::QuitWhenIdleClosure());
290 RunLoop().Run(); 289 RunLoop().Run();
291 290
292 EXPECT_EQ(12, injector()->processed_events()); 291 EXPECT_EQ(12, injector()->processed_events());
293 } 292 }
294 293
295 namespace { 294 namespace {
296 295
(...skipping 20 matching lines...) Expand all
317 } 316 }
318 } 317 }
319 318
320 void FromEvent() { 319 void FromEvent() {
321 if (event_count_ > 0) { 320 if (event_count_ > 0) {
322 --event_count_; 321 --event_count_;
323 } 322 }
324 if (task_count_ == 0 && event_count_ == 0) { 323 if (task_count_ == 0 && event_count_ == 0) {
325 MessageLoop::current()->QuitWhenIdle(); 324 MessageLoop::current()->QuitWhenIdle();
326 } else { 325 } else {
327 injector_->AddEventAsTask( 326 injector_->AddEventAsTask(0,
328 0, Bind(&ConcurrentHelper::FromEvent, this)); 327 BindOnce(&ConcurrentHelper::FromEvent, this));
329 } 328 }
330 } 329 }
331 330
332 int event_count() const { return event_count_; } 331 int event_count() const { return event_count_; }
333 int task_count() const { return task_count_; } 332 int task_count() const { return task_count_; }
334 333
335 private: 334 private:
336 friend class RefCounted<ConcurrentHelper>; 335 friend class RefCounted<ConcurrentHelper>;
337 336
338 ~ConcurrentHelper() {} 337 ~ConcurrentHelper() {}
(...skipping 11 matching lines...) Expand all
350 TEST_F(MessagePumpGLibTest, TestConcurrentEventPostedTask) { 349 TEST_F(MessagePumpGLibTest, TestConcurrentEventPostedTask) {
351 // Tests that posted tasks don't starve events, nor the opposite. 350 // Tests that posted tasks don't starve events, nor the opposite.
352 // We use the helper class above. We keep both event and posted task queues 351 // We use the helper class above. We keep both event and posted task queues
353 // full, the helper verifies that both tasks and events get processed. 352 // full, the helper verifies that both tasks and events get processed.
354 // If that is not the case, either event_count_ or task_count_ will not get 353 // If that is not the case, either event_count_ or task_count_ will not get
355 // to 0, and MessageLoop::QuitWhenIdle() will never be called. 354 // to 0, and MessageLoop::QuitWhenIdle() will never be called.
356 scoped_refptr<ConcurrentHelper> helper = new ConcurrentHelper(injector()); 355 scoped_refptr<ConcurrentHelper> helper = new ConcurrentHelper(injector());
357 356
358 // Add 2 events to the queue to make sure it is always full (when we remove 357 // Add 2 events to the queue to make sure it is always full (when we remove
359 // the event before processing it). 358 // the event before processing it).
360 injector()->AddEventAsTask( 359 injector()->AddEventAsTask(0, BindOnce(&ConcurrentHelper::FromEvent, helper));
361 0, Bind(&ConcurrentHelper::FromEvent, helper)); 360 injector()->AddEventAsTask(0, BindOnce(&ConcurrentHelper::FromEvent, helper));
362 injector()->AddEventAsTask(
363 0, Bind(&ConcurrentHelper::FromEvent, helper));
364 361
365 // Similarly post 2 tasks. 362 // Similarly post 2 tasks.
366 loop()->task_runner()->PostTask( 363 loop()->task_runner()->PostTask(
367 FROM_HERE, BindOnce(&ConcurrentHelper::FromTask, helper)); 364 FROM_HERE, BindOnce(&ConcurrentHelper::FromTask, helper));
368 loop()->task_runner()->PostTask( 365 loop()->task_runner()->PostTask(
369 FROM_HERE, BindOnce(&ConcurrentHelper::FromTask, helper)); 366 FROM_HERE, BindOnce(&ConcurrentHelper::FromTask, helper));
370 367
371 RunLoop().Run(); 368 RunLoop().Run();
372 EXPECT_EQ(0, helper->event_count()); 369 EXPECT_EQ(0, helper->event_count());
373 EXPECT_EQ(0, helper->task_count()); 370 EXPECT_EQ(0, helper->task_count());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // Tests that events and posted tasks are correctly executed if the message 517 // Tests that events and posted tasks are correctly executed if the message
521 // loop is not run by MessageLoop::Run() but by a straight Gtk loop. 518 // loop is not run by MessageLoop::Run() but by a straight Gtk loop.
522 // Note that in this case we don't make strong guarantees about niceness 519 // Note that in this case we don't make strong guarantees about niceness
523 // between events and posted tasks. 520 // between events and posted tasks.
524 loop()->task_runner()->PostTask( 521 loop()->task_runner()->PostTask(
525 FROM_HERE, BindOnce(&TestGtkLoopInternal, Unretained(injector()))); 522 FROM_HERE, BindOnce(&TestGtkLoopInternal, Unretained(injector())));
526 RunLoop().Run(); 523 RunLoop().Run();
527 } 524 }
528 525
529 } // namespace base 526 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698