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

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

Issue 1011683002: Lazily initialize MessageLoop for faster thread startup (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed comments Created 5 years, 7 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 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
7 7
8 #include <queue> 8 #include <queue>
9 #include <string> 9 #include <string>
10 10
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 enum Type { 102 enum Type {
103 TYPE_DEFAULT, 103 TYPE_DEFAULT,
104 TYPE_UI, 104 TYPE_UI,
105 TYPE_CUSTOM, 105 TYPE_CUSTOM,
106 TYPE_IO, 106 TYPE_IO,
107 #if defined(OS_ANDROID) 107 #if defined(OS_ANDROID)
108 TYPE_JAVA, 108 TYPE_JAVA,
109 #endif // defined(OS_ANDROID) 109 #endif // defined(OS_ANDROID)
110 }; 110 };
111 111
112 using MessagePumpFactoryCallback = Callback<scoped_ptr<MessagePump>()>;
113
114 // Creates a MessageLoop of |type|. If |type| is TYPE_CUSTOM
115 // non-null |pump_factory| must be also given to create a message pump
116 // for this message loop. Otherwise a default message pump for
117 // the |type| is created.
118 //
119 // It is valid to create a new message loop on one thread, and then pass
120 // it to the thread where the message loop actually runs. The message
121 // loop's BindToCurrentThread() method must be called on the thread
122 // the message loop runs on, before calling Run().
Nico 2015/04/27 22:49:34 I'm not sure how to best communicate what can be d
kinuko 2015/04/28 15:43:25 Yeah that might be less confusing. In the new CL
123 //
112 // Normally, it is not necessary to instantiate a MessageLoop. Instead, it 124 // Normally, it is not necessary to instantiate a MessageLoop. Instead, it
113 // is typical to make use of the current thread's MessageLoop instance. 125 // is typical to make use of the current thread's MessageLoop instance.
126 MessageLoop(Type type, MessagePumpFactoryCallback pump_factory);
127
128 // TODO(kinuko): Cleanup these non-default constructors in a follow-up CL
129 // for crbug.com/465458.
130 // Creates a MessageLoop of |type| for the current thread. Usually this
131 // constructor is used only for testing. No need to call Init if the
132 // message loop is constructed this way.
114 explicit MessageLoop(Type type = TYPE_DEFAULT); 133 explicit MessageLoop(Type type = TYPE_DEFAULT);
115 // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must 134 // Creates a TYPE_CUSTOM MessageLoop for the current thread with the
116 // be non-NULL. 135 // supplied MessagePump, which must be non-NULL. Usually used only for
117 explicit MessageLoop(scoped_ptr<base::MessagePump> pump); 136 // testing. No need to call Init if the message loop is constructed this way.
Nico 2015/04/27 22:49:34 s/Init/BindToCurrentThread/ (I still think it's w
kinuko 2015/04/28 15:43:25 Done.
137 explicit MessageLoop(scoped_ptr<MessagePump> pump);
138
118 ~MessageLoop() override; 139 ~MessageLoop() override;
119 140
120 // Returns the MessageLoop object for the current thread, or null if none. 141 // Returns the MessageLoop object for the current thread, or null if none.
121 static MessageLoop* current(); 142 static MessageLoop* current();
122 143
123 static void EnableHistogrammer(bool enable_histogrammer); 144 static void EnableHistogrammer(bool enable_histogrammer);
124 145
125 typedef scoped_ptr<MessagePump> (MessagePumpFactory)(); 146 typedef scoped_ptr<MessagePump> (MessagePumpFactory)();
126 // Uses the given base::MessagePumpForUIFactory to override the default 147 // Uses the given base::MessagePumpForUIFactory to override the default
127 // MessagePump implementation for 'TYPE_UI'. Returns true if the factory 148 // MessagePump implementation for 'TYPE_UI'. Returns true if the factory
(...skipping 12 matching lines...) Expand all
140 // not be run. Instead, they will be deleted. 161 // not be run. Instead, they will be deleted.
141 // 162 //
142 class BASE_EXPORT DestructionObserver { 163 class BASE_EXPORT DestructionObserver {
143 public: 164 public:
144 virtual void WillDestroyCurrentMessageLoop() = 0; 165 virtual void WillDestroyCurrentMessageLoop() = 0;
145 166
146 protected: 167 protected:
147 virtual ~DestructionObserver(); 168 virtual ~DestructionObserver();
148 }; 169 };
149 170
171 // Configure various members and bind this message loop to the current thread.
172 void BindToCurrentThread();
173
150 // Add a DestructionObserver, which will start receiving notifications 174 // Add a DestructionObserver, which will start receiving notifications
151 // immediately. 175 // immediately.
152 void AddDestructionObserver(DestructionObserver* destruction_observer); 176 void AddDestructionObserver(DestructionObserver* destruction_observer);
153 177
154 // Remove a DestructionObserver. It is safe to call this method while a 178 // Remove a DestructionObserver. It is safe to call this method while a
155 // DestructionObserver is receiving a notification callback. 179 // DestructionObserver is receiving a notification callback.
156 void RemoveDestructionObserver(DestructionObserver* destruction_observer); 180 void RemoveDestructionObserver(DestructionObserver* destruction_observer);
157 181
158 // NOTE: Deprecated; prefer task_runner() and the TaskRunner interfaces. 182 // NOTE: Deprecated; prefer task_runner() and the TaskRunner interfaces.
159 // TODO(skyostil): Remove these functions (crbug.com/465354). 183 // TODO(skyostil): Remove these functions (crbug.com/465354).
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 void QuitNow(); 293 void QuitNow();
270 294
271 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure(). 295 // TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure().
272 static Closure QuitClosure() { return QuitWhenIdleClosure(); } 296 static Closure QuitClosure() { return QuitWhenIdleClosure(); }
273 297
274 // Deprecated: use RunLoop instead. 298 // Deprecated: use RunLoop instead.
275 // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an 299 // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an
276 // arbitrary MessageLoop to QuitWhenIdle. 300 // arbitrary MessageLoop to QuitWhenIdle.
277 static Closure QuitWhenIdleClosure(); 301 static Closure QuitWhenIdleClosure();
278 302
279 // Set the timer slack for this message loop. 303 // Set the timer slack for this message loop.
Nico 2015/04/27 22:49:34 // Must not be called before BindToCurrentThread()
280 void SetTimerSlack(TimerSlack timer_slack) { 304 void SetTimerSlack(TimerSlack timer_slack) {
281 pump_->SetTimerSlack(timer_slack); 305 pump_->SetTimerSlack(timer_slack);
282 } 306 }
283 307
284 // Returns true if this loop is |type|. This allows subclasses (especially 308 // Returns true if this loop is |type|. This allows subclasses (especially
285 // those in tests) to specialize how they are identified. 309 // those in tests) to specialize how they are identified.
286 virtual bool IsType(Type type) const; 310 virtual bool IsType(Type type) const;
287 311
288 // Returns the type passed to the constructor. 312 // Returns the type passed to the constructor.
289 Type type() const { return type_; } 313 Type type() const { return type_; }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 // The specific case where tasks get queued is: 345 // The specific case where tasks get queued is:
322 // - The thread is running a message loop. 346 // - The thread is running a message loop.
323 // - It receives a task #1 and execute it. 347 // - It receives a task #1 and execute it.
324 // - The task #1 implicitly start a message loop, like a MessageBox in the 348 // - The task #1 implicitly start a message loop, like a MessageBox in the
325 // unit test. This can also be StartDoc or GetSaveFileName. 349 // unit test. This can also be StartDoc or GetSaveFileName.
326 // - The thread receives a task #2 before or while in this second message 350 // - The thread receives a task #2 before or while in this second message
327 // loop. 351 // loop.
328 // - With NestableTasksAllowed set to true, the task #2 will run right away. 352 // - With NestableTasksAllowed set to true, the task #2 will run right away.
329 // Otherwise, it will get executed right after task #1 completes at "thread 353 // Otherwise, it will get executed right after task #1 completes at "thread
330 // message loop level". 354 // message loop level".
331 void SetNestableTasksAllowed(bool allowed); 355 void SetNestableTasksAllowed(bool allowed);
Nico 2015/04/27 22:49:34 // Must not be called before BindToCurrentThread()
332 bool NestableTasksAllowed() const; 356 bool NestableTasksAllowed() const;
333 357
334 // Enables nestable tasks on |loop| while in scope. 358 // Enables nestable tasks on |loop| while in scope.
335 class ScopedNestableTaskAllower { 359 class ScopedNestableTaskAllower {
336 public: 360 public:
337 explicit ScopedNestableTaskAllower(MessageLoop* loop) 361 explicit ScopedNestableTaskAllower(MessageLoop* loop)
338 : loop_(loop), 362 : loop_(loop),
339 old_state_(loop_->NestableTasksAllowed()) { 363 old_state_(loop_->NestableTasksAllowed()) {
340 loop_->SetNestableTasksAllowed(true); 364 loop_->SetNestableTasksAllowed(true);
341 } 365 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 // Can only be called from the thread that owns the MessageLoop. 411 // Can only be called from the thread that owns the MessageLoop.
388 bool is_running() const; 412 bool is_running() const;
389 413
390 // Returns true if the message loop has high resolution timers enabled. 414 // Returns true if the message loop has high resolution timers enabled.
391 // Provided for testing. 415 // Provided for testing.
392 bool HasHighResolutionTasks(); 416 bool HasHighResolutionTasks();
393 417
394 // Returns true if the message loop is "idle". Provided for testing. 418 // Returns true if the message loop is "idle". Provided for testing.
395 bool IsIdleForTesting(); 419 bool IsIdleForTesting();
396 420
397 // Wakes up the message pump. Can be called on any thread. The caller is
398 // responsible for synchronizing ScheduleWork() calls.
399 void ScheduleWork();
400
401 // Returns the TaskAnnotator which is used to add debug information to posted 421 // Returns the TaskAnnotator which is used to add debug information to posted
402 // tasks. 422 // tasks.
403 debug::TaskAnnotator* task_annotator() { return &task_annotator_; } 423 debug::TaskAnnotator* task_annotator() { return &task_annotator_; }
404 424
405 // Runs the specified PendingTask. 425 // Runs the specified PendingTask.
406 void RunTask(const PendingTask& pending_task); 426 void RunTask(const PendingTask& pending_task);
407 427
408 //---------------------------------------------------------------------------- 428 //----------------------------------------------------------------------------
409 protected: 429 protected:
410 scoped_ptr<MessagePump> pump_; 430 scoped_ptr<MessagePump> pump_;
411 431
412 private: 432 private:
413 friend class RunLoop; 433 friend class RunLoop;
434 friend class internal::IncomingTaskQueue;
435 friend class ScheduleWorkTest;
414 436
415 // Configures various members for the two constructors. 437 // Wakes up the message pump. Can be called on any thread. The caller is
416 void Init(); 438 // responsible for synchronizing ScheduleWork() calls.
439 void ScheduleWork();
417 440
418 // Invokes the actual run loop using the message pump. 441 // Invokes the actual run loop using the message pump.
419 void RunHandler(); 442 void RunHandler();
420 443
421 // Called to process any delayed non-nestable tasks. 444 // Called to process any delayed non-nestable tasks.
422 bool ProcessNextDelayedNonNestableTask(); 445 bool ProcessNextDelayedNonNestableTask();
423 446
424 // Calls RunTask or queues the pending_task on the deferred task list if it 447 // Calls RunTask or queues the pending_task on the deferred task list if it
425 // cannot be run right now. Returns true if the task was run. 448 // cannot be run right now. Returns true if the task was run.
426 bool DeferOrRunPendingTask(const PendingTask& pending_task); 449 bool DeferOrRunPendingTask(const PendingTask& pending_task);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 // A recursion block that prevents accidentally running additional tasks when 506 // A recursion block that prevents accidentally running additional tasks when
484 // insider a (accidentally induced?) nested message pump. 507 // insider a (accidentally induced?) nested message pump.
485 bool nestable_tasks_allowed_; 508 bool nestable_tasks_allowed_;
486 509
487 #if defined(OS_WIN) 510 #if defined(OS_WIN)
488 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc 511 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
489 // which enter a modal message loop. 512 // which enter a modal message loop.
490 bool os_modal_loop_; 513 bool os_modal_loop_;
491 #endif 514 #endif
492 515
516 // pump_factory_.Run() is called to create a message pump for this loop
517 // if type_ is TYPE_CUSTOM and pump_ is null.
518 MessagePumpFactoryCallback pump_factory_;
519
493 std::string thread_name_; 520 std::string thread_name_;
494 // A profiling histogram showing the counts of various messages and events. 521 // A profiling histogram showing the counts of various messages and events.
495 HistogramBase* message_histogram_; 522 HistogramBase* message_histogram_;
496 523
497 RunLoop* run_loop_; 524 RunLoop* run_loop_;
498 525
499 ObserverList<TaskObserver> task_observers_; 526 ObserverList<TaskObserver> task_observers_;
500 527
501 debug::TaskAnnotator task_annotator_; 528 debug::TaskAnnotator task_annotator_;
502 529
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 681
655 // Do not add any member variables to MessageLoopForIO! This is important b/c 682 // Do not add any member variables to MessageLoopForIO! This is important b/c
656 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 683 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra
657 // data that you need should be stored on the MessageLoop's pump_ instance. 684 // data that you need should be stored on the MessageLoop's pump_ instance.
658 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 685 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
659 MessageLoopForIO_should_not_have_extra_member_variables); 686 MessageLoopForIO_should_not_have_extra_member_variables);
660 687
661 } // namespace base 688 } // namespace base
662 689
663 #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 690 #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698