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

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

Powered by Google App Engine
This is Rietveld 408576698