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

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: non-blocking thread_id() 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();
rvargas (doing something else) 2015/03/26 02:19:26 no need to Pass()
kinuko 2015/04/13 02:02:59 Done.
303 } else {
304 pump_ =
305 CreateMessagePumpForType(lazy_init_options_->message_loop_type).Pass();
rvargas (doing something else) 2015/03/26 02:19:27 no need to Pass()
kinuko 2015/04/13 02:02:59 Done.
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 19 matching lines...) Expand all
292 } 345 }
293 346
294 void MessageLoop::PostNonNestableDelayedTask( 347 void MessageLoop::PostNonNestableDelayedTask(
295 const tracked_objects::Location& from_here, 348 const tracked_objects::Location& from_here,
296 const Closure& task, 349 const Closure& task,
297 TimeDelta delay) { 350 TimeDelta delay) {
298 message_loop_proxy_->PostNonNestableDelayedTask(from_here, task, delay); 351 message_loop_proxy_->PostNonNestableDelayedTask(from_here, task, delay);
299 } 352 }
300 353
301 void MessageLoop::Run() { 354 void MessageLoop::Run() {
355 DCHECK(!lazy_init_options_);
302 RunLoop run_loop; 356 RunLoop run_loop;
303 run_loop.Run(); 357 run_loop.Run();
304 } 358 }
305 359
306 void MessageLoop::RunUntilIdle() { 360 void MessageLoop::RunUntilIdle() {
361 DCHECK(!lazy_init_options_);
307 RunLoop run_loop; 362 RunLoop run_loop;
308 run_loop.RunUntilIdle(); 363 run_loop.RunUntilIdle();
309 } 364 }
310 365
311 void MessageLoop::QuitWhenIdle() { 366 void MessageLoop::QuitWhenIdle() {
312 DCHECK_EQ(this, current()); 367 DCHECK_EQ(this, current());
313 if (run_loop_) { 368 if (run_loop_) {
314 run_loop_->quit_when_idle_received_ = true; 369 run_loop_->quit_when_idle_received_ = true;
315 } else { 370 } else {
316 NOTREACHED() << "Must be inside Run to call Quit"; 371 NOTREACHED() << "Must be inside Run to call Quit";
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 } 431 }
377 432
378 bool MessageLoop::IsIdleForTesting() { 433 bool MessageLoop::IsIdleForTesting() {
379 // We only check the imcoming queue|, since we don't want to lock the work 434 // We only check the imcoming queue|, since we don't want to lock the work
380 // queue. 435 // queue.
381 return incoming_task_queue_->IsIdleForTesting(); 436 return incoming_task_queue_->IsIdleForTesting();
382 } 437 }
383 438
384 //------------------------------------------------------------------------------ 439 //------------------------------------------------------------------------------
385 440
441 MessageLoop::MessageLoop(scoped_ptr<LazyInitOptions> options)
442 : type_(GetMessageLoopType(options.get())),
443 #if defined(OS_WIN)
444 pending_high_res_tasks_(0),
445 in_high_res_mode_(false),
446 #endif
447 nestable_tasks_allowed_(true),
448 #if defined(OS_WIN)
449 os_modal_loop_(false),
450 #endif // OS_WIN
451 lazy_init_options_(options.Pass()),
452 message_histogram_(NULL),
453 run_loop_(NULL) {
454 incoming_task_queue_ =
455 internal::IncomingTaskQueue::CreateForLazyInitMessageLoop(this);
456 message_loop_proxy_ =
457 internal::MessageLoopProxyImpl::CreateForLazyInit(incoming_task_queue_);
458 }
459
386 void MessageLoop::Init() { 460 void MessageLoop::Init() {
461 DCHECK(!lazy_init_options_) << "should not be called when created for "
462 "lazy initialization";
387 DCHECK(!current()) << "should only have one message loop per thread"; 463 DCHECK(!current()) << "should only have one message loop per thread";
388 lazy_tls_ptr.Pointer()->Set(this); 464 lazy_tls_ptr.Pointer()->Set(this);
389 465
390 incoming_task_queue_ = new internal::IncomingTaskQueue(this); 466 incoming_task_queue_ = new internal::IncomingTaskQueue(this);
391 message_loop_proxy_ = 467 message_loop_proxy_ =
392 new internal::MessageLoopProxyImpl(incoming_task_queue_); 468 internal::MessageLoopProxyImpl::Create(incoming_task_queue_);
393 thread_task_runner_handle_.reset( 469 thread_task_runner_handle_.reset(
394 new ThreadTaskRunnerHandle(message_loop_proxy_)); 470 new ThreadTaskRunnerHandle(message_loop_proxy_));
395 } 471 }
396 472
397 void MessageLoop::RunHandler() { 473 void MessageLoop::RunHandler() {
398 DCHECK_EQ(this, current()); 474 DCHECK_EQ(this, current());
399 475
400 StartHistogrammer(); 476 StartHistogrammer();
401 477
402 #if defined(OS_WIN) 478 #if defined(OS_WIN)
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 persistent, 787 persistent,
712 mode, 788 mode,
713 controller, 789 controller,
714 delegate); 790 delegate);
715 } 791 }
716 #endif 792 #endif
717 793
718 #endif // !defined(OS_NACL_SFI) 794 #endif // !defined(OS_NACL_SFI)
719 795
720 } // namespace base 796 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698