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

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

Issue 1011683002: Lazily initialize MessageLoop for faster thread startup (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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.h" 5 #include "base/message_loop/message_loop.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 #elif defined(OS_POSIX) 93 #elif defined(OS_POSIX)
94 typedef MessagePumpLibevent MessagePumpForIO; 94 typedef MessagePumpLibevent MessagePumpForIO;
95 #endif 95 #endif
96 96
97 #if !defined(OS_NACL_SFI) 97 #if !defined(OS_NACL_SFI)
98 MessagePumpForIO* ToPumpIO(MessagePump* pump) { 98 MessagePumpForIO* ToPumpIO(MessagePump* pump) {
99 return static_cast<MessagePumpForIO*>(pump); 99 return static_cast<MessagePumpForIO*>(pump);
100 } 100 }
101 #endif // !defined(OS_NACL_SFI) 101 #endif // !defined(OS_NACL_SFI)
102 102
103 MessageLoop::Type GetMessageLoopType(MessageLoop::LazyInitOptions* options) {
104 if (options->message_pump_factory.is_null())
105 return options->message_loop_type;
106 return MessageLoop::TYPE_CUSTOM;
107 }
108
103 } // namespace 109 } // namespace
104 110
105 //------------------------------------------------------------------------------ 111 //------------------------------------------------------------------------------
106 112
113 MessageLoop::LazyInitOptions::LazyInitOptions()
114 : message_loop_type(MessageLoop::TYPE_DEFAULT),
115 timer_slack(TIMER_SLACK_NONE) {
116 }
117
118 MessageLoop::LazyInitOptions::~LazyInitOptions() {
119 }
120
121 //------------------------------------------------------------------------------
122
107 MessageLoop::TaskObserver::TaskObserver() { 123 MessageLoop::TaskObserver::TaskObserver() {
108 } 124 }
109 125
110 MessageLoop::TaskObserver::~TaskObserver() { 126 MessageLoop::TaskObserver::~TaskObserver() {
111 } 127 }
112 128
113 MessageLoop::DestructionObserver::~DestructionObserver() { 129 MessageLoop::DestructionObserver::~DestructionObserver() {
114 } 130 }
115 131
116 //------------------------------------------------------------------------------ 132 //------------------------------------------------------------------------------
(...skipping 26 matching lines...) Expand all
143 #if defined(OS_WIN) 159 #if defined(OS_WIN)
144 os_modal_loop_(false), 160 os_modal_loop_(false),
145 #endif // OS_WIN 161 #endif // OS_WIN
146 message_histogram_(NULL), 162 message_histogram_(NULL),
147 run_loop_(NULL) { 163 run_loop_(NULL) {
148 DCHECK(pump_.get()); 164 DCHECK(pump_.get());
149 Init(); 165 Init();
150 } 166 }
151 167
152 MessageLoop::~MessageLoop() { 168 MessageLoop::~MessageLoop() {
169 if (lazy_init_options_) {
170 // This message loop is destructed before we call LazyInit.
171 DCHECK(current() == NULL);
172 DCHECK(incoming_task_queue_->empty());
173 DCHECK(!pump_);
174 DCHECK(!destruction_observers_.might_have_observers());
175 incoming_task_queue_->WillDestroyCurrentMessageLoop();
176 return;
177 }
178
153 DCHECK_EQ(this, current()); 179 DCHECK_EQ(this, current());
154 180
155 // iOS just attaches to the loop, it doesn't Run it. 181 // iOS just attaches to the loop, it doesn't Run it.
156 // TODO(stuartmorgan): Consider wiring up a Detach(). 182 // TODO(stuartmorgan): Consider wiring up a Detach().
157 #if !defined(OS_IOS) 183 #if !defined(OS_IOS)
158 DCHECK(!run_loop_); 184 DCHECK(!run_loop_);
159 #endif 185 #endif
160 186
161 #if defined(OS_WIN) 187 #if defined(OS_WIN)
162 if (in_high_res_mode_) 188 if (in_high_res_mode_)
(...skipping 25 matching lines...) Expand all
188 // Tell the incoming queue that we are dying. 214 // Tell the incoming queue that we are dying.
189 incoming_task_queue_->WillDestroyCurrentMessageLoop(); 215 incoming_task_queue_->WillDestroyCurrentMessageLoop();
190 incoming_task_queue_ = NULL; 216 incoming_task_queue_ = NULL;
191 message_loop_proxy_ = NULL; 217 message_loop_proxy_ = NULL;
192 218
193 // OK, now make it so that no one can find us. 219 // OK, now make it so that no one can find us.
194 lazy_tls_ptr.Pointer()->Set(NULL); 220 lazy_tls_ptr.Pointer()->Set(NULL);
195 } 221 }
196 222
197 // static 223 // static
224 MessageLoop* MessageLoop::CreateForLazyInit(
225 scoped_ptr<LazyInitOptions> options) {
226 return new MessageLoop(options.Pass());
227 }
228
229 // static
198 MessageLoop* MessageLoop::current() { 230 MessageLoop* MessageLoop::current() {
199 // TODO(darin): sadly, we cannot enable this yet since people call us even 231 // TODO(darin): sadly, we cannot enable this yet since people call us even
200 // when they have no intention of using us. 232 // when they have no intention of using us.
201 // DCHECK(loop) << "Ouch, did you forget to initialize me?"; 233 // DCHECK(loop) << "Ouch, did you forget to initialize me?";
202 return lazy_tls_ptr.Pointer()->Get(); 234 return lazy_tls_ptr.Pointer()->Get();
203 } 235 }
204 236
205 // static 237 // static
206 void MessageLoop::EnableHistogrammer(bool enable) { 238 void MessageLoop::EnableHistogrammer(bool enable) {
207 enable_histogrammer_ = enable; 239 enable_histogrammer_ = enable;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 285
254 #if defined(OS_ANDROID) 286 #if defined(OS_ANDROID)
255 if (type == MessageLoop::TYPE_JAVA) 287 if (type == MessageLoop::TYPE_JAVA)
256 return scoped_ptr<MessagePump>(new MessagePumpForUI()); 288 return scoped_ptr<MessagePump>(new MessagePumpForUI());
257 #endif 289 #endif
258 290
259 DCHECK_EQ(MessageLoop::TYPE_DEFAULT, type); 291 DCHECK_EQ(MessageLoop::TYPE_DEFAULT, type);
260 return MESSAGE_PUMP_DEFAULT; 292 return MESSAGE_PUMP_DEFAULT;
261 } 293 }
262 294
295 void MessageLoop::LazyInit() {
296 DCHECK(lazy_init_options_)
297 << "should be called only when created for lazy init";
298 DCHECK(!current()) << "should only have one message loop per thread";
299 lazy_tls_ptr.Pointer()->Set(this);
300
301 if (!lazy_init_options_->message_pump_factory.is_null()) {
302 pump_ = lazy_init_options_->message_pump_factory.Run().Pass();
303 } else {
304 pump_ =
305 CreateMessagePumpForType(lazy_init_options_->message_loop_type).Pass();
306 }
307 SetTimerSlack(lazy_init_options_->timer_slack);
308 lazy_init_options_.reset();
309
310 incoming_task_queue_->DidInitializeMessageLoop();
311 message_loop_proxy_->LazyInit();
312 thread_task_runner_handle_.reset(
313 new ThreadTaskRunnerHandle(message_loop_proxy_));
314 }
315
263 void MessageLoop::AddDestructionObserver( 316 void MessageLoop::AddDestructionObserver(
264 DestructionObserver* destruction_observer) { 317 DestructionObserver* destruction_observer) {
265 DCHECK_EQ(this, current()); 318 DCHECK_EQ(this, current());
266 destruction_observers_.AddObserver(destruction_observer); 319 destruction_observers_.AddObserver(destruction_observer);
267 } 320 }
268 321
269 void MessageLoop::RemoveDestructionObserver( 322 void MessageLoop::RemoveDestructionObserver(
270 DestructionObserver* destruction_observer) { 323 DestructionObserver* destruction_observer) {
271 DCHECK_EQ(this, current()); 324 DCHECK_EQ(this, current());
272 destruction_observers_.RemoveObserver(destruction_observer); 325 destruction_observers_.RemoveObserver(destruction_observer);
(...skipping 23 matching lines...) Expand all
296 349
297 void MessageLoop::PostNonNestableDelayedTask( 350 void MessageLoop::PostNonNestableDelayedTask(
298 const tracked_objects::Location& from_here, 351 const tracked_objects::Location& from_here,
299 const Closure& task, 352 const Closure& task,
300 TimeDelta delay) { 353 TimeDelta delay) {
301 DCHECK(!task.is_null()) << from_here.ToString(); 354 DCHECK(!task.is_null()) << from_here.ToString();
302 incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, false); 355 incoming_task_queue_->AddToIncomingQueue(from_here, task, delay, false);
303 } 356 }
304 357
305 void MessageLoop::Run() { 358 void MessageLoop::Run() {
359 DCHECK(!lazy_init_options_);
306 RunLoop run_loop; 360 RunLoop run_loop;
307 run_loop.Run(); 361 run_loop.Run();
308 } 362 }
309 363
310 void MessageLoop::RunUntilIdle() { 364 void MessageLoop::RunUntilIdle() {
365 DCHECK(!lazy_init_options_);
311 RunLoop run_loop; 366 RunLoop run_loop;
312 run_loop.RunUntilIdle(); 367 run_loop.RunUntilIdle();
313 } 368 }
314 369
315 void MessageLoop::QuitWhenIdle() { 370 void MessageLoop::QuitWhenIdle() {
316 DCHECK_EQ(this, current()); 371 DCHECK_EQ(this, current());
317 if (run_loop_) { 372 if (run_loop_) {
318 run_loop_->quit_when_idle_received_ = true; 373 run_loop_->quit_when_idle_received_ = true;
319 } else { 374 } else {
320 NOTREACHED() << "Must be inside Run to call Quit"; 375 NOTREACHED() << "Must be inside Run to call Quit";
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 } 435 }
381 436
382 bool MessageLoop::IsIdleForTesting() { 437 bool MessageLoop::IsIdleForTesting() {
383 // We only check the imcoming queue|, since we don't want to lock the work 438 // We only check the imcoming queue|, since we don't want to lock the work
384 // queue. 439 // queue.
385 return incoming_task_queue_->IsIdleForTesting(); 440 return incoming_task_queue_->IsIdleForTesting();
386 } 441 }
387 442
388 //------------------------------------------------------------------------------ 443 //------------------------------------------------------------------------------
389 444
445 MessageLoop::MessageLoop(scoped_ptr<LazyInitOptions> options)
446 : type_(GetMessageLoopType(options.get())),
447 #if defined(OS_WIN)
448 pending_high_res_tasks_(0),
449 in_high_res_mode_(false),
450 #endif
451 nestable_tasks_allowed_(true),
452 #if defined(OS_WIN)
453 os_modal_loop_(false),
454 #endif // OS_WIN
455 lazy_init_options_(options.Pass()),
456 message_histogram_(NULL),
457 run_loop_(NULL) {
458 incoming_task_queue_ =
459 internal::IncomingTaskQueue::CreateForLazyInitMessageLoop(this);
460 message_loop_proxy_ =
461 internal::MessageLoopProxyImpl::CreateForLazyInit(incoming_task_queue_);
462 }
463
390 void MessageLoop::Init() { 464 void MessageLoop::Init() {
465 DCHECK(!lazy_init_options_) << "should not be called when created for "
466 "lazy initialization";
391 DCHECK(!current()) << "should only have one message loop per thread"; 467 DCHECK(!current()) << "should only have one message loop per thread";
392 lazy_tls_ptr.Pointer()->Set(this); 468 lazy_tls_ptr.Pointer()->Set(this);
393 469
394 incoming_task_queue_ = new internal::IncomingTaskQueue(this); 470 incoming_task_queue_ = new internal::IncomingTaskQueue(this);
395 message_loop_proxy_ = 471 message_loop_proxy_ =
396 new internal::MessageLoopProxyImpl(incoming_task_queue_); 472 internal::MessageLoopProxyImpl::Create(incoming_task_queue_);
397 thread_task_runner_handle_.reset( 473 thread_task_runner_handle_.reset(
398 new ThreadTaskRunnerHandle(message_loop_proxy_)); 474 new ThreadTaskRunnerHandle(message_loop_proxy_));
399 } 475 }
400 476
401 void MessageLoop::RunHandler() { 477 void MessageLoop::RunHandler() {
402 DCHECK_EQ(this, current()); 478 DCHECK_EQ(this, current());
403 479
404 StartHistogrammer(); 480 StartHistogrammer();
405 481
406 #if defined(OS_WIN) 482 #if defined(OS_WIN)
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 persistent, 791 persistent,
716 mode, 792 mode,
717 controller, 793 controller,
718 delegate); 794 delegate);
719 } 795 }
720 #endif 796 #endif
721 797
722 #endif // !defined(OS_NACL_SFI) 798 #endif // !defined(OS_NACL_SFI)
723 799
724 } // namespace base 800 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698