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

Side by Side Diff: base/message_loop.h

Issue 6463013: Add support for base::Closure in the MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: Fix merge error. Created 9 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 | Annotate | Revision Log
« no previous file with comments | « base/bind_internal_win.h.pump ('k') | base/message_loop.cc » ('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 #ifndef BASE_MESSAGE_LOOP_H_ 5 #ifndef BASE_MESSAGE_LOOP_H_
6 #define BASE_MESSAGE_LOOP_H_ 6 #define BASE_MESSAGE_LOOP_H_
7 #pragma once 7 #pragma once
8 8
9 #include <queue> 9 #include <queue>
10 #include <string> 10 #include <string>
11 11
12 #include "base/base_api.h" 12 #include "base/base_api.h"
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/callback.h"
14 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
15 #include "base/message_pump.h" 16 #include "base/message_pump.h"
16 #include "base/observer_list.h" 17 #include "base/observer_list.h"
17 #include "base/synchronization/lock.h" 18 #include "base/synchronization/lock.h"
18 #include "base/task.h" 19 #include "base/task.h"
20 #include "base/time.h"
21 #include "base/tracked.h"
19 22
20 #if defined(OS_WIN) 23 #if defined(OS_WIN)
21 // We need this to declare base::MessagePumpWin::Dispatcher, which we should 24 // We need this to declare base::MessagePumpWin::Dispatcher, which we should
22 // really just eliminate. 25 // really just eliminate.
23 #include "base/message_pump_win.h" 26 #include "base/message_pump_win.h"
24 #elif defined(OS_POSIX) 27 #elif defined(OS_POSIX)
25 #include "base/message_pump_libevent.h" 28 #include "base/message_pump_libevent.h"
26 #if !defined(OS_MACOSX) 29 #if !defined(OS_MACOSX)
27 #include "base/message_pump_glib.h" 30 #include "base/message_pump_glib.h"
28 typedef struct _XDisplay Display; 31 typedef struct _XDisplay Display;
29 #endif 32 #endif
30 #endif 33 #endif
31 #if defined(TOUCH_UI) 34 #if defined(TOUCH_UI)
32 #include "base/message_pump_glib_x_dispatch.h" 35 #include "base/message_pump_glib_x_dispatch.h"
33 #endif 36 #endif
34 37
35 namespace base { 38 namespace base {
36 class Histogram; 39 class Histogram;
37 } 40 }
38 41
42 #if defined(TRACK_ALL_TASK_OBJECTS)
43 namespace tracked_objects {
44 class Births;
45 }
46 #endif // defined(TRACK_ALL_TASK_OBJECTS)
47
39 // A MessageLoop is used to process events for a particular thread. There is 48 // A MessageLoop is used to process events for a particular thread. There is
40 // at most one MessageLoop instance per thread. 49 // at most one MessageLoop instance per thread.
41 // 50 //
42 // Events include at a minimum Task instances submitted to PostTask or those 51 // Events include at a minimum Task instances submitted to PostTask or those
43 // managed by TimerManager. Depending on the type of message pump used by the 52 // managed by TimerManager. Depending on the type of message pump used by the
44 // MessageLoop other events such as UI messages may be processed. On Windows 53 // MessageLoop other events such as UI messages may be processed. On Windows
45 // APC calls (as time permits) and signals sent to a registered set of HANDLEs 54 // APC calls (as time permits) and signals sent to a registered set of HANDLEs
46 // may also be processed. 55 // may also be processed.
47 // 56 //
48 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called 57 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 165
157 void PostDelayedTask( 166 void PostDelayedTask(
158 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); 167 const tracked_objects::Location& from_here, Task* task, int64 delay_ms);
159 168
160 void PostNonNestableTask( 169 void PostNonNestableTask(
161 const tracked_objects::Location& from_here, Task* task); 170 const tracked_objects::Location& from_here, Task* task);
162 171
163 void PostNonNestableDelayedTask( 172 void PostNonNestableDelayedTask(
164 const tracked_objects::Location& from_here, Task* task, int64 delay_ms); 173 const tracked_objects::Location& from_here, Task* task, int64 delay_ms);
165 174
175 void PostClosure(
176 const tracked_objects::Location& from_here,
177 const base::Closure& closure);
178
179 void PostDelayedClosure(
180 const tracked_objects::Location& from_here,
181 const base::Closure& closure, int64 delay_ms);
182
183 void PostNonNestableClosure(
184 const tracked_objects::Location& from_here,
185 const base::Closure& closure);
186
187 void PostNonNestableDelayedClosure(
188 const tracked_objects::Location& from_here,
189 const base::Closure& closure, int64 delay_ms);
190
166 // A variant on PostTask that deletes the given object. This is useful 191 // A variant on PostTask that deletes the given object. This is useful
167 // if the object needs to live until the next run of the MessageLoop (for 192 // if the object needs to live until the next run of the MessageLoop (for
168 // example, deleting a RenderProcessHost from within an IPC callback is not 193 // example, deleting a RenderProcessHost from within an IPC callback is not
169 // good). 194 // good).
170 // 195 //
171 // NOTE: This method may be called on any thread. The object will be deleted 196 // NOTE: This method may be called on any thread. The object will be deleted
172 // on the thread that executes MessageLoop::Run(). If this is not the same 197 // on the thread that executes MessageLoop::Run(). If this is not the same
173 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit 198 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit
174 // from RefCountedThreadSafe<T>! 199 // from RefCountedThreadSafe<T>!
175 template <class T> 200 template <class T>
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 // exception filter that was active when Run() was called. This can happen 298 // exception filter that was active when Run() was called. This can happen
274 // if some third party code call SetUnhandledExceptionFilter() and never 299 // if some third party code call SetUnhandledExceptionFilter() and never
275 // restores the previous filter. 300 // restores the previous filter.
276 void set_exception_restoration(bool restore) { 301 void set_exception_restoration(bool restore) {
277 exception_restoration_ = restore; 302 exception_restoration_ = restore;
278 } 303 }
279 304
280 // Returns true if we are currently running a nested message loop. 305 // Returns true if we are currently running a nested message loop.
281 bool IsNested(); 306 bool IsNested();
282 307
283 // A TaskObserver is an object that receives task notifications from the 308 // A ClosureObserver is an object that receives task notifications from the
284 // MessageLoop. 309 // MessageLoop.
285 // 310 //
286 // NOTE: A TaskObserver implementation should be extremely fast! 311 // NOTE: A ClosureObserver implementation should be extremely fast!
287 class BASE_API TaskObserver { 312 class BASE_API ClosureObserver {
Mike Belshe 2011/04/13 04:16:58 Even if "ClosureObserver" is more accurate than "T
288 public: 313 public:
289 TaskObserver(); 314 ClosureObserver();
290 315
291 // This method is called before processing a task. 316 // This method is called before processing a task.
292 virtual void WillProcessTask(const Task* task) = 0; 317 virtual void WillProcessClosure(base::TimeTicks time_posted) = 0;
293 318
294 // This method is called after processing a task. 319 // This method is called after processing a task.
295 virtual void DidProcessTask(const Task* task) = 0; 320 virtual void DidProcessClosure(base::TimeTicks time_posted) = 0;
296 321
297 protected: 322 protected:
298 virtual ~TaskObserver(); 323 virtual ~ClosureObserver();
299 }; 324 };
300 325
301 // These functions can only be called on the same thread that |this| is 326 // These functions can only be called on the same thread that |this| is
302 // running on. 327 // running on.
303 void AddTaskObserver(TaskObserver* task_observer); 328 void AddClosureObserver(ClosureObserver* closure_observer);
304 void RemoveTaskObserver(TaskObserver* task_observer); 329 void RemoveClosureObserver(ClosureObserver* closure_observer);
305 330
306 // Returns true if the message loop has high resolution timers enabled. 331 // Returns true if the message loop has high resolution timers enabled.
307 // Provided for testing. 332 // Provided for testing.
308 bool high_resolution_timers_enabled() { 333 bool high_resolution_timers_enabled() {
309 #if defined(OS_WIN) 334 #if defined(OS_WIN)
310 return !high_resolution_timer_expiration_.is_null(); 335 return !high_resolution_timer_expiration_.is_null();
311 #else 336 #else
312 return true; 337 return true;
313 #endif 338 #endif
314 } 339 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 class AutoRunState : RunState { 373 class AutoRunState : RunState {
349 public: 374 public:
350 explicit AutoRunState(MessageLoop* loop); 375 explicit AutoRunState(MessageLoop* loop);
351 ~AutoRunState(); 376 ~AutoRunState();
352 private: 377 private:
353 MessageLoop* loop_; 378 MessageLoop* loop_;
354 RunState* previous_state_; 379 RunState* previous_state_;
355 }; 380 };
356 381
357 // This structure is copied around by value. 382 // This structure is copied around by value.
358 struct PendingTask { 383 struct PendingClosure {
Mike Belshe 2011/04/13 04:16:58 Similar comment here. The name "PendingClosure" s
359 PendingTask(Task* task, bool nestable) 384 PendingClosure(const base::Closure& closure,
360 : task(task), sequence_num(0), nestable(nestable) { 385 const tracked_objects::Location& posted_from,
361 } 386 base::TimeTicks delayed_run_time,
387 bool nestable);
362 388
363 // Used to support sorting. 389 // Used to support sorting.
364 bool operator<(const PendingTask& other) const; 390 bool operator<(const PendingClosure& other) const;
365 391
366 Task* task; // The task to run. 392 // The Closure to run.
367 base::TimeTicks delayed_run_time; // The time when the task should be run. 393 base::Closure closure;
368 int sequence_num; // Secondary sort key for run time. 394
369 bool nestable; // OK to dispatch from a nested loop. 395 #if defined(TRACK_ALL_TASK_OBJECTS)
396 // Counter for location where the Closure was posted from.
397 tracked_objects::Births* post_births;
398 #endif // defined(TRACK_ALL_TASK_OBJECTS)
399
400 // Time this PendingClosure was posted.
401 base::TimeTicks time_posted;
402
403 // The time when the task should be run.
404 base::TimeTicks delayed_run_time;
405
406 // Secondary sort key for run time.
407 int sequence_num;
408
409 // OK to dispatch from a nested loop.
410 bool nestable;
370 }; 411 };
371 412
372 class TaskQueue : public std::queue<PendingTask> { 413 class TaskQueue : public std::queue<PendingClosure> {
Mike Belshe 2011/04/13 04:16:58 Ah - precedent - thank you for not changing this t
373 public: 414 public:
374 void Swap(TaskQueue* queue) { 415 void Swap(TaskQueue* queue) {
375 c.swap(queue->c); // Calls std::deque::swap 416 c.swap(queue->c); // Calls std::deque::swap
376 } 417 }
377 }; 418 };
378 419
379 typedef std::priority_queue<PendingTask> DelayedTaskQueue; 420 typedef std::priority_queue<PendingClosure> DelayedTaskQueue;
380 421
381 #if defined(OS_WIN) 422 #if defined(OS_WIN)
382 base::MessagePumpWin* pump_win() { 423 base::MessagePumpWin* pump_win() {
383 return static_cast<base::MessagePumpWin*>(pump_.get()); 424 return static_cast<base::MessagePumpWin*>(pump_.get());
384 } 425 }
385 #elif defined(OS_POSIX) 426 #elif defined(OS_POSIX)
386 base::MessagePumpLibevent* pump_libevent() { 427 base::MessagePumpLibevent* pump_libevent() {
387 return static_cast<base::MessagePumpLibevent*>(pump_.get()); 428 return static_cast<base::MessagePumpLibevent*>(pump_.get());
388 } 429 }
389 #endif 430 #endif
390 431
391 // A function to encapsulate all the exception handling capability in the 432 // A function to encapsulate all the exception handling capability in the
392 // stacks around the running of a main message loop. It will run the message 433 // stacks around the running of a main message loop. It will run the message
393 // loop in a SEH try block or not depending on the set_SEH_restoration() 434 // loop in a SEH try block or not depending on the set_SEH_restoration()
394 // flag invoking respectively RunInternalInSEHFrame() or RunInternal(). 435 // flag invoking respectively RunInternalInSEHFrame() or RunInternal().
395 void RunHandler(); 436 void RunHandler();
396 437
397 #if defined(OS_WIN) 438 #if defined(OS_WIN)
398 __declspec(noinline) void RunInternalInSEHFrame(); 439 __declspec(noinline) void RunInternalInSEHFrame();
399 #endif 440 #endif
400 441
401 // A surrounding stack frame around the running of the message loop that 442 // A surrounding stack frame around the running of the message loop that
402 // supports all saving and restoring of state, as is needed for any/all (ugly) 443 // supports all saving and restoring of state, as is needed for any/all (ugly)
403 // recursive calls. 444 // recursive calls.
404 void RunInternal(); 445 void RunInternal();
405 446
406 // Called to process any delayed non-nestable tasks. 447 // Called to process any delayed non-nestable tasks.
407 bool ProcessNextDelayedNonNestableTask(); 448 bool ProcessNextDelayedNonNestableTask();
408 449
409 // Runs the specified task and deletes it. 450 // Runs the specified PendingClosure.
410 void RunTask(Task* task); 451 void RunClosure(const PendingClosure& closure);
411 452
412 // Calls RunTask or queues the pending_task on the deferred task list if it 453 // Calls RunTask or queues the pending_closure on the deferred task list if it
413 // cannot be run right now. Returns true if the task was run. 454 // cannot be run right now. Returns true if the task was run.
414 bool DeferOrRunPendingTask(const PendingTask& pending_task); 455 bool DeferOrRunPendingClosure(const PendingClosure& pending_closure);
415 456
416 // Adds the pending task to delayed_work_queue_. 457 // Adds the pending task to delayed_work_queue_.
417 void AddToDelayedWorkQueue(const PendingTask& pending_task); 458 void AddToDelayedWorkQueue(const PendingClosure& pending_closure);
459
460 // Adds the pending task to our incoming_queue_.
461 //
462 // Caller retains ownership of |pending_closure|, but this function will
463 // reset the value of pending_closure->closure. This is needed to ensure
464 // that the posting call stack does not retain pending_closure->closure
465 // beyond this function call.
466 void AddToIncomingQueue(PendingClosure* pending_closure);
418 467
419 // Load tasks from the incoming_queue_ into work_queue_ if the latter is 468 // Load tasks from the incoming_queue_ into work_queue_ if the latter is
420 // empty. The former requires a lock to access, while the latter is directly 469 // empty. The former requires a lock to access, while the latter is directly
421 // accessible on this thread. 470 // accessible on this thread.
422 void ReloadWorkQueue(); 471 void ReloadWorkQueue();
423 472
424 // Delete tasks that haven't run yet without running them. Used in the 473 // Delete tasks that haven't run yet without running them. Used in the
425 // destructor to make sure all the task's destructors get called. Returns 474 // destructor to make sure all the task's destructors get called. Returns
426 // true if some work was done. 475 // true if some work was done.
427 bool DeletePendingTasks(); 476 bool DeletePendingClosures();
428 477
429 // Post a task to our incomming queue. 478 // Calcuates the time at which a PendingClosure should run.
430 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, 479 base::TimeTicks CalculateDelayedRuntime(int64 delay_ms);
431 int64 delay_ms, bool nestable);
432 480
433 // Start recording histogram info about events and action IF it was enabled 481 // Start recording histogram info about events and action IF it was enabled
434 // and IF the statistics recorder can accept a registration of our histogram. 482 // and IF the statistics recorder can accept a registration of our histogram.
435 void StartHistogrammer(); 483 void StartHistogrammer();
436 484
437 // Add occurence of event to our histogram, so that we can see what is being 485 // Add occurence of event to our histogram, so that we can see what is being
438 // done in a specific MessageLoop instance (i.e., specific thread). 486 // done in a specific MessageLoop instance (i.e., specific thread).
439 // If message_histogram_ is NULL, this is a no-op. 487 // If message_histogram_ is NULL, this is a no-op.
440 void HistogramEvent(int event); 488 void HistogramEvent(int event);
441 489
(...skipping 28 matching lines...) Expand all
470 bool nestable_tasks_allowed_; 518 bool nestable_tasks_allowed_;
471 519
472 bool exception_restoration_; 520 bool exception_restoration_;
473 521
474 std::string thread_name_; 522 std::string thread_name_;
475 // A profiling histogram showing the counts of various messages and events. 523 // A profiling histogram showing the counts of various messages and events.
476 base::Histogram* message_histogram_; 524 base::Histogram* message_histogram_;
477 525
478 // A null terminated list which creates an incoming_queue of tasks that are 526 // A null terminated list which creates an incoming_queue of tasks that are
479 // acquired under a mutex for processing on this instance's thread. These 527 // acquired under a mutex for processing on this instance's thread. These
480 // tasks have not yet been sorted out into items for our work_queue_ vs 528 // tasks have not yet been sorted out into items for our work_queue_ vs items
481 // items that will be handled by the TimerManager. 529 // that will be handled by the TimerManager.
482 TaskQueue incoming_queue_; 530 TaskQueue incoming_queue_;
483 // Protect access to incoming_queue_. 531 // Protect access to incoming_queue_.
484 mutable base::Lock incoming_queue_lock_; 532 mutable base::Lock incoming_queue_lock_;
485 533
486 RunState* state_; 534 RunState* state_;
487 535
536 bool should_leak_tasks_;
537
488 #if defined(OS_WIN) 538 #if defined(OS_WIN)
489 base::TimeTicks high_resolution_timer_expiration_; 539 base::TimeTicks high_resolution_timer_expiration_;
490 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc 540 // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
491 // which enter a modal message loop. 541 // which enter a modal message loop.
492 bool os_modal_loop_; 542 bool os_modal_loop_;
493 #endif 543 #endif
494 544
495 // The next sequence number to use for delayed tasks. 545 // The next sequence number to use for delayed tasks.
496 int next_sequence_num_; 546 int next_sequence_num_;
497 547
498 ObserverList<TaskObserver> task_observers_; 548 ObserverList<ClosureObserver> closure_observers_;
499 549
500 private: 550 private:
501 DISALLOW_COPY_AND_ASSIGN(MessageLoop); 551 DISALLOW_COPY_AND_ASSIGN(MessageLoop);
502 }; 552 };
503 553
504 //----------------------------------------------------------------------------- 554 //-----------------------------------------------------------------------------
505 // MessageLoopForUI extends MessageLoop with methods that are particular to a 555 // MessageLoopForUI extends MessageLoop with methods that are particular to a
506 // MessageLoop instantiated with TYPE_UI. 556 // MessageLoop instantiated with TYPE_UI.
507 // 557 //
508 // This class is typically used like so: 558 // This class is typically used like so:
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 #endif // defined(OS_POSIX) 678 #endif // defined(OS_POSIX)
629 }; 679 };
630 680
631 // Do not add any member variables to MessageLoopForIO! This is important b/c 681 // Do not add any member variables to MessageLoopForIO! This is important b/c
632 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 682 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra
633 // data that you need should be stored on the MessageLoop's pump_ instance. 683 // data that you need should be stored on the MessageLoop's pump_ instance.
634 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 684 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO),
635 MessageLoopForIO_should_not_have_extra_member_variables); 685 MessageLoopForIO_should_not_have_extra_member_variables);
636 686
637 #endif // BASE_MESSAGE_LOOP_H_ 687 #endif // BASE_MESSAGE_LOOP_H_
OLDNEW
« no previous file with comments | « base/bind_internal_win.h.pump ('k') | base/message_loop.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698