| OLD | NEW |
| 1 // Copyright (c) 2006-2008 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 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 // MessageLoop::current()->SetNestableTasksAllowed(true); | 59 // MessageLoop::current()->SetNestableTasksAllowed(true); |
| 60 // HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here. | 60 // HRESULT hr = DoDragDrop(...); // Implicitly runs a modal message loop here. |
| 61 // MessageLoop::current()->SetNestableTasksAllowed(old_state); | 61 // MessageLoop::current()->SetNestableTasksAllowed(old_state); |
| 62 // // Process hr (the result returned by DoDragDrop(). | 62 // // Process hr (the result returned by DoDragDrop(). |
| 63 // | 63 // |
| 64 // Please be SURE your task is reentrant (nestable) and all global variables | 64 // Please be SURE your task is reentrant (nestable) and all global variables |
| 65 // are stable and accessible before calling SetNestableTasksAllowed(true). | 65 // are stable and accessible before calling SetNestableTasksAllowed(true). |
| 66 // | 66 // |
| 67 class MessageLoop : public base::MessagePump::Delegate { | 67 class MessageLoop : public base::MessagePump::Delegate { |
| 68 public: | 68 public: |
| 69 // A TaskObserver is an object that receives task notifications from the | 69 #if defined(OS_WIN) |
| 70 // MessageLoop. | 70 typedef base::MessagePumpWin::Dispatcher Dispatcher; |
| 71 typedef base::MessagePumpForUI::Observer Observer; |
| 72 #elif !defined(OS_MACOSX) |
| 73 #if defined(TOUCH_UI) |
| 74 typedef base::MessagePumpGlibXDispatcher Dispatcher; |
| 75 #else |
| 76 typedef base::MessagePumpForUI::Dispatcher Dispatcher; |
| 77 #endif |
| 78 typedef base::MessagePumpForUI::Observer Observer; |
| 79 #endif |
| 80 |
| 81 // A MessageLoop has a particular type, which indicates the set of |
| 82 // asynchronous events it may process in addition to tasks and timers. |
| 71 // | 83 // |
| 72 // NOTE: A TaskObserver implementation should be extremely fast! | 84 // TYPE_DEFAULT |
| 73 class TaskObserver { | 85 // This type of ML only supports tasks and timers. |
| 74 public: | 86 // |
| 75 TaskObserver(); | 87 // TYPE_UI |
| 88 // This type of ML also supports native UI events (e.g., Windows messages). |
| 89 // See also MessageLoopForUI. |
| 90 // |
| 91 // TYPE_IO |
| 92 // This type of ML also supports asynchronous IO. See also |
| 93 // MessageLoopForIO. |
| 94 // |
| 95 enum Type { |
| 96 TYPE_DEFAULT, |
| 97 TYPE_UI, |
| 98 TYPE_IO |
| 99 }; |
| 76 | 100 |
| 77 // This method is called before processing a task. | 101 // Normally, it is not necessary to instantiate a MessageLoop. Instead, it |
| 78 virtual void WillProcessTask(const Task* task) = 0; | 102 // is typical to make use of the current thread's MessageLoop instance. |
| 79 | 103 explicit MessageLoop(Type type = TYPE_DEFAULT); |
| 80 // This method is called after processing a task. | 104 ~MessageLoop(); |
| 81 virtual void DidProcessTask(const Task* task) = 0; | |
| 82 | |
| 83 protected: | |
| 84 virtual ~TaskObserver(); | |
| 85 }; | |
| 86 | 105 |
| 87 static void EnableHistogrammer(bool enable_histogrammer); | 106 static void EnableHistogrammer(bool enable_histogrammer); |
| 88 | 107 |
| 89 // A DestructionObserver is notified when the current MessageLoop is being | 108 // A DestructionObserver is notified when the current MessageLoop is being |
| 90 // destroyed. These obsevers are notified prior to MessageLoop::current() | 109 // destroyed. These obsevers are notified prior to MessageLoop::current() |
| 91 // being changed to return NULL. This gives interested parties the chance to | 110 // being changed to return NULL. This gives interested parties the chance to |
| 92 // do final cleanup that depends on the MessageLoop. | 111 // do final cleanup that depends on the MessageLoop. |
| 93 // | 112 // |
| 94 // NOTE: Any tasks posted to the MessageLoop during this notification will | 113 // NOTE: Any tasks posted to the MessageLoop during this notification will |
| 95 // not be run. Instead, they will be deleted. | 114 // not be run. Instead, they will be deleted. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 212 |
| 194 // Invokes Quit on the current MessageLoop when run. Useful to schedule an | 213 // Invokes Quit on the current MessageLoop when run. Useful to schedule an |
| 195 // arbitrary MessageLoop to Quit. | 214 // arbitrary MessageLoop to Quit. |
| 196 class QuitTask : public Task { | 215 class QuitTask : public Task { |
| 197 public: | 216 public: |
| 198 virtual void Run() { | 217 virtual void Run() { |
| 199 MessageLoop::current()->Quit(); | 218 MessageLoop::current()->Quit(); |
| 200 } | 219 } |
| 201 }; | 220 }; |
| 202 | 221 |
| 203 // A MessageLoop has a particular type, which indicates the set of | |
| 204 // asynchronous events it may process in addition to tasks and timers. | |
| 205 // | |
| 206 // TYPE_DEFAULT | |
| 207 // This type of ML only supports tasks and timers. | |
| 208 // | |
| 209 // TYPE_UI | |
| 210 // This type of ML also supports native UI events (e.g., Windows messages). | |
| 211 // See also MessageLoopForUI. | |
| 212 // | |
| 213 // TYPE_IO | |
| 214 // This type of ML also supports asynchronous IO. See also | |
| 215 // MessageLoopForIO. | |
| 216 // | |
| 217 enum Type { | |
| 218 TYPE_DEFAULT, | |
| 219 TYPE_UI, | |
| 220 TYPE_IO | |
| 221 }; | |
| 222 | |
| 223 // Normally, it is not necessary to instantiate a MessageLoop. Instead, it | |
| 224 // is typical to make use of the current thread's MessageLoop instance. | |
| 225 explicit MessageLoop(Type type = TYPE_DEFAULT); | |
| 226 ~MessageLoop(); | |
| 227 | |
| 228 // Returns the type passed to the constructor. | 222 // Returns the type passed to the constructor. |
| 229 Type type() const { return type_; } | 223 Type type() const { return type_; } |
| 230 | 224 |
| 231 // Optional call to connect the thread name with this loop. | 225 // Optional call to connect the thread name with this loop. |
| 232 void set_thread_name(const std::string& thread_name) { | 226 void set_thread_name(const std::string& thread_name) { |
| 233 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; | 227 DCHECK(thread_name_.empty()) << "Should not rename this thread!"; |
| 234 thread_name_ = thread_name; | 228 thread_name_ = thread_name; |
| 235 } | 229 } |
| 236 const std::string& thread_name() const { return thread_name_; } | 230 const std::string& thread_name() const { return thread_name_; } |
| 237 | 231 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 // exception filter that was active when Run() was called. This can happen | 271 // exception filter that was active when Run() was called. This can happen |
| 278 // if some third party code call SetUnhandledExceptionFilter() and never | 272 // if some third party code call SetUnhandledExceptionFilter() and never |
| 279 // restores the previous filter. | 273 // restores the previous filter. |
| 280 void set_exception_restoration(bool restore) { | 274 void set_exception_restoration(bool restore) { |
| 281 exception_restoration_ = restore; | 275 exception_restoration_ = restore; |
| 282 } | 276 } |
| 283 | 277 |
| 284 // Returns true if we are currently running a nested message loop. | 278 // Returns true if we are currently running a nested message loop. |
| 285 bool IsNested(); | 279 bool IsNested(); |
| 286 | 280 |
| 281 // A TaskObserver is an object that receives task notifications from the |
| 282 // MessageLoop. |
| 283 // |
| 284 // NOTE: A TaskObserver implementation should be extremely fast! |
| 285 class TaskObserver { |
| 286 public: |
| 287 TaskObserver(); |
| 288 |
| 289 // This method is called before processing a task. |
| 290 virtual void WillProcessTask(const Task* task) = 0; |
| 291 |
| 292 // This method is called after processing a task. |
| 293 virtual void DidProcessTask(const Task* task) = 0; |
| 294 |
| 295 protected: |
| 296 virtual ~TaskObserver(); |
| 297 }; |
| 298 |
| 287 // These functions can only be called on the same thread that |this| is | 299 // These functions can only be called on the same thread that |this| is |
| 288 // running on. | 300 // running on. |
| 289 void AddTaskObserver(TaskObserver* task_observer); | 301 void AddTaskObserver(TaskObserver* task_observer); |
| 290 void RemoveTaskObserver(TaskObserver* task_observer); | 302 void RemoveTaskObserver(TaskObserver* task_observer); |
| 291 | 303 |
| 292 #if defined(OS_WIN) | |
| 293 typedef base::MessagePumpWin::Dispatcher Dispatcher; | |
| 294 typedef base::MessagePumpForUI::Observer Observer; | |
| 295 #elif !defined(OS_MACOSX) | |
| 296 #if defined(TOUCH_UI) | |
| 297 typedef base::MessagePumpGlibXDispatcher Dispatcher; | |
| 298 #else | |
| 299 typedef base::MessagePumpForUI::Dispatcher Dispatcher; | |
| 300 #endif | |
| 301 typedef base::MessagePumpForUI::Observer Observer; | |
| 302 #endif | |
| 303 | |
| 304 // Returns true if the message loop has high resolution timers enabled. | 304 // Returns true if the message loop has high resolution timers enabled. |
| 305 // Provided for testing. | 305 // Provided for testing. |
| 306 bool high_resolution_timers_enabled() { | 306 bool high_resolution_timers_enabled() { |
| 307 #if defined(OS_WIN) | 307 #if defined(OS_WIN) |
| 308 return !high_resolution_timer_expiration_.is_null(); | 308 return !high_resolution_timer_expiration_.is_null(); |
| 309 #else | 309 #else |
| 310 return true; | 310 return true; |
| 311 #endif | 311 #endif |
| 312 } | 312 } |
| 313 | 313 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 334 public: | 334 public: |
| 335 explicit AutoRunState(MessageLoop* loop); | 335 explicit AutoRunState(MessageLoop* loop); |
| 336 ~AutoRunState(); | 336 ~AutoRunState(); |
| 337 private: | 337 private: |
| 338 MessageLoop* loop_; | 338 MessageLoop* loop_; |
| 339 RunState* previous_state_; | 339 RunState* previous_state_; |
| 340 }; | 340 }; |
| 341 | 341 |
| 342 // This structure is copied around by value. | 342 // This structure is copied around by value. |
| 343 struct PendingTask { | 343 struct PendingTask { |
| 344 Task* task; // The task to run. | |
| 345 base::TimeTicks delayed_run_time; // The time when the task should be run. | |
| 346 int sequence_num; // Secondary sort key for run time. | |
| 347 bool nestable; // OK to dispatch from a nested loop. | |
| 348 | |
| 349 PendingTask(Task* task, bool nestable) | 344 PendingTask(Task* task, bool nestable) |
| 350 : task(task), sequence_num(0), nestable(nestable) { | 345 : task(task), sequence_num(0), nestable(nestable) { |
| 351 } | 346 } |
| 352 | 347 |
| 353 // Used to support sorting. | 348 // Used to support sorting. |
| 354 bool operator<(const PendingTask& other) const; | 349 bool operator<(const PendingTask& other) const; |
| 350 |
| 351 Task* task; // The task to run. |
| 352 base::TimeTicks delayed_run_time; // The time when the task should be run. |
| 353 int sequence_num; // Secondary sort key for run time. |
| 354 bool nestable; // OK to dispatch from a nested loop. |
| 355 }; | 355 }; |
| 356 | 356 |
| 357 class TaskQueue : public std::queue<PendingTask> { | 357 class TaskQueue : public std::queue<PendingTask> { |
| 358 public: | 358 public: |
| 359 void Swap(TaskQueue* queue) { | 359 void Swap(TaskQueue* queue) { |
| 360 c.swap(queue->c); // Calls std::deque::swap | 360 c.swap(queue->c); // Calls std::deque::swap |
| 361 } | 361 } |
| 362 }; | 362 }; |
| 363 | 363 |
| 364 typedef std::priority_queue<PendingTask> DelayedTaskQueue; | 364 typedef std::priority_queue<PendingTask> DelayedTaskQueue; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 | 420 |
| 421 // Delete tasks that haven't run yet without running them. Used in the | 421 // Delete tasks that haven't run yet without running them. Used in the |
| 422 // destructor to make sure all the task's destructors get called. Returns | 422 // destructor to make sure all the task's destructors get called. Returns |
| 423 // true if some work was done. | 423 // true if some work was done. |
| 424 bool DeletePendingTasks(); | 424 bool DeletePendingTasks(); |
| 425 | 425 |
| 426 // Post a task to our incomming queue. | 426 // Post a task to our incomming queue. |
| 427 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, | 427 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, |
| 428 int64 delay_ms, bool nestable); | 428 int64 delay_ms, bool nestable); |
| 429 | 429 |
| 430 // base::MessagePump::Delegate methods: | |
| 431 virtual bool DoWork(); | |
| 432 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time); | |
| 433 virtual bool DoIdleWork(); | |
| 434 | |
| 435 // Start recording histogram info about events and action IF it was enabled | 430 // Start recording histogram info about events and action IF it was enabled |
| 436 // and IF the statistics recorder can accept a registration of our histogram. | 431 // and IF the statistics recorder can accept a registration of our histogram. |
| 437 void StartHistogrammer(); | 432 void StartHistogrammer(); |
| 438 | 433 |
| 439 // Add occurence of event to our histogram, so that we can see what is being | 434 // Add occurence of event to our histogram, so that we can see what is being |
| 440 // done in a specific MessageLoop instance (i.e., specific thread). | 435 // done in a specific MessageLoop instance (i.e., specific thread). |
| 441 // If message_histogram_ is NULL, this is a no-op. | 436 // If message_histogram_ is NULL, this is a no-op. |
| 442 void HistogramEvent(int event); | 437 void HistogramEvent(int event); |
| 443 | 438 |
| 439 // base::MessagePump::Delegate methods: |
| 440 virtual bool DoWork(); |
| 441 virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time); |
| 442 virtual bool DoIdleWork(); |
| 443 |
| 444 Type type_; | 444 Type type_; |
| 445 | 445 |
| 446 // A list of tasks that need to be processed by this instance. Note that | 446 // A list of tasks that need to be processed by this instance. Note that |
| 447 // this queue is only accessed (push/pop) by our current thread. | 447 // this queue is only accessed (push/pop) by our current thread. |
| 448 TaskQueue work_queue_; | 448 TaskQueue work_queue_; |
| 449 | 449 |
| 450 // Contains delayed tasks, sorted by their 'delayed_run_time' property. | 450 // Contains delayed tasks, sorted by their 'delayed_run_time' property. |
| 451 DelayedTaskQueue delayed_work_queue_; | 451 DelayedTaskQueue delayed_work_queue_; |
| 452 | 452 |
| 453 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. | 453 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 #endif // defined(OS_POSIX) | 609 #endif // defined(OS_POSIX) |
| 610 }; | 610 }; |
| 611 | 611 |
| 612 // Do not add any member variables to MessageLoopForIO! This is important b/c | 612 // Do not add any member variables to MessageLoopForIO! This is important b/c |
| 613 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 613 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
| 614 // data that you need should be stored on the MessageLoop's pump_ instance. | 614 // data that you need should be stored on the MessageLoop's pump_ instance. |
| 615 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 615 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
| 616 MessageLoopForIO_should_not_have_extra_member_variables); | 616 MessageLoopForIO_should_not_have_extra_member_variables); |
| 617 | 617 |
| 618 #endif // BASE_MESSAGE_LOOP_H_ | 618 #endif // BASE_MESSAGE_LOOP_H_ |
| OLD | NEW |