OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <queue> | 9 #include <queue> |
10 #include <string> | 10 #include <string> |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 }; | 73 }; |
74 | 74 |
75 // Add a DestructionObserver, which will start receiving notifications | 75 // Add a DestructionObserver, which will start receiving notifications |
76 // immediately. | 76 // immediately. |
77 void AddDestructionObserver(DestructionObserver* destruction_observer); | 77 void AddDestructionObserver(DestructionObserver* destruction_observer); |
78 | 78 |
79 // Remove a DestructionObserver. It is safe to call this method while a | 79 // Remove a DestructionObserver. It is safe to call this method while a |
80 // DestructionObserver is receiving a notification callback. | 80 // DestructionObserver is receiving a notification callback. |
81 void RemoveDestructionObserver(DestructionObserver* destruction_observer); | 81 void RemoveDestructionObserver(DestructionObserver* destruction_observer); |
82 | 82 |
83 // Call the task's Run method asynchronously from within a message loop at | 83 // The "PostTask" family of methods call the task's Run method asynchronously |
84 // some point in the future. With the PostTask variant, tasks are invoked in | 84 // from within a message loop at some point in the future. |
85 // FIFO order, inter-mixed with normal UI event processing. With the | |
86 // PostDelayedTask variant, tasks are called after at least approximately | |
87 // 'delay_ms' have elapsed. | |
88 // | 85 // |
89 // The MessageLoop takes ownership of the Task, and deletes it after it | 86 // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed |
90 // has been Run(). | 87 // with normal UI or IO event processing. With the PostDelayedTask variant, |
| 88 // tasks are called after at least approximately 'delay_ms' have elapsed. |
91 // | 89 // |
92 // NOTE: This method may be called on any thread. The Task will be invoked | 90 // The NonNestable variants work similarly except that they promise never to |
| 91 // dispatch the task from a nested invocation of MessageLoop::Run. Instead, |
| 92 // such tasks get deferred until the top-most MessageLoop::Run is executing. |
| 93 // |
| 94 // The MessageLoop takes ownership of the Task, and deletes it after it has |
| 95 // been Run(). |
| 96 // |
| 97 // NOTE: These methods may be called on any thread. The Task will be invoked |
93 // on the thread that executes MessageLoop::Run(). | 98 // on the thread that executes MessageLoop::Run(). |
| 99 |
| 100 void PostTask( |
| 101 const tracked_objects::Location& from_here, Task* task); |
| 102 |
| 103 void PostDelayedTask( |
| 104 const tracked_objects::Location& from_here, Task* task, int delay_ms); |
94 | 105 |
95 void PostTask(const tracked_objects::Location& from_here, Task* task) { | 106 void PostNonNestableTask( |
96 PostDelayedTask(from_here, task, 0); | 107 const tracked_objects::Location& from_here, Task* task); |
97 } | |
98 | 108 |
99 void PostDelayedTask(const tracked_objects::Location& from_here, Task* task, | 109 void PostNonNestableDelayedTask( |
100 int delay_ms); | 110 const tracked_objects::Location& from_here, Task* task, int delay_ms); |
101 | 111 |
102 // A variant on PostTask that deletes the given object. This is useful | 112 // A variant on PostTask that deletes the given object. This is useful |
103 // if the object needs to live until the next run of the MessageLoop (for | 113 // if the object needs to live until the next run of the MessageLoop (for |
104 // example, deleting a RenderProcessHost from within an IPC callback is not | 114 // example, deleting a RenderProcessHost from within an IPC callback is not |
105 // good). | 115 // good). |
106 // | 116 // |
107 // NOTE: This method may be called on any thread. The object will be deleted | 117 // NOTE: This method may be called on any thread. The object will be deleted |
108 // on the thread that executes MessageLoop::Run(). If this is not the same | 118 // on the thread that executes MessageLoop::Run(). If this is not the same |
109 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit | 119 // as the thread that calls PostDelayedTask(FROM_HERE, ), then T MUST inherit |
110 // from RefCountedThreadSafe<T>! | 120 // from RefCountedThreadSafe<T>! |
111 template <class T> | 121 template <class T> |
112 void DeleteSoon(const tracked_objects::Location& from_here, T* object) { | 122 void DeleteSoon(const tracked_objects::Location& from_here, T* object) { |
113 PostTask(from_here, new DeleteTask<T>(object)); | 123 PostNonNestableTask(from_here, new DeleteTask<T>(object)); |
114 } | 124 } |
115 | 125 |
116 // A variant on PostTask that releases the given reference counted object | 126 // A variant on PostTask that releases the given reference counted object |
117 // (by calling its Release method). This is useful if the object needs to | 127 // (by calling its Release method). This is useful if the object needs to |
118 // live until the next run of the MessageLoop, or if the object needs to be | 128 // live until the next run of the MessageLoop, or if the object needs to be |
119 // released on a particular thread. | 129 // released on a particular thread. |
120 // | 130 // |
121 // NOTE: This method may be called on any thread. The object will be | 131 // NOTE: This method may be called on any thread. The object will be |
122 // released (and thus possibly deleted) on the thread that executes | 132 // released (and thus possibly deleted) on the thread that executes |
123 // MessageLoop::Run(). If this is not the same as the thread that calls | 133 // MessageLoop::Run(). If this is not the same as the thread that calls |
124 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from | 134 // PostDelayedTask(FROM_HERE, ), then T MUST inherit from |
125 // RefCountedThreadSafe<T>! | 135 // RefCountedThreadSafe<T>! |
126 template <class T> | 136 template <class T> |
127 void ReleaseSoon(const tracked_objects::Location& from_here, T* object) { | 137 void ReleaseSoon(const tracked_objects::Location& from_here, T* object) { |
128 PostTask(from_here, new ReleaseTask<T>(object)); | 138 PostNonNestableTask(from_here, new ReleaseTask<T>(object)); |
129 } | 139 } |
130 | 140 |
131 // Run the message loop. | 141 // Run the message loop. |
132 void Run(); | 142 void Run(); |
133 | 143 |
134 // Process all pending tasks, windows messages, etc., but don't wait/sleep. | 144 // Process all pending tasks, windows messages, etc., but don't wait/sleep. |
135 // Return as soon as all items that can be run are taken care of. | 145 // Return as soon as all items that can be run are taken care of. |
136 void RunAllPending(); | 146 void RunAllPending(); |
137 | 147 |
138 // Signals the Run method to return after it is done processing all pending | 148 // Signals the Run method to return after it is done processing all pending |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 202 |
193 // Returns the MessageLoop object for the current thread, or null if none. | 203 // Returns the MessageLoop object for the current thread, or null if none. |
194 static MessageLoop* current() { | 204 static MessageLoop* current() { |
195 MessageLoop* loop = static_cast<MessageLoop*>(tls_index_.Get()); | 205 MessageLoop* loop = static_cast<MessageLoop*>(tls_index_.Get()); |
196 // TODO(darin): sadly, we cannot enable this yet since people call us even | 206 // TODO(darin): sadly, we cannot enable this yet since people call us even |
197 // when they have no intention of using us. | 207 // when they have no intention of using us. |
198 //DCHECK(loop) << "Ouch, did you forget to initialize me?"; | 208 //DCHECK(loop) << "Ouch, did you forget to initialize me?"; |
199 return loop; | 209 return loop; |
200 } | 210 } |
201 | 211 |
202 // Returns the TimerManager object for the current thread. This getter is | |
203 // deprecated. Please use OneShotTimer or RepeatingTimer instead. | |
204 base::TimerManager* timer_manager_deprecated() { return &timer_manager_; } | |
205 | |
206 // Enables or disables the recursive task processing. This happens in the case | 212 // Enables or disables the recursive task processing. This happens in the case |
207 // of recursive message loops. Some unwanted message loop may occurs when | 213 // of recursive message loops. Some unwanted message loop may occurs when |
208 // using common controls or printer functions. By default, recursive task | 214 // using common controls or printer functions. By default, recursive task |
209 // processing is disabled. | 215 // processing is disabled. |
210 // | 216 // |
211 // The specific case where tasks get queued is: | 217 // The specific case where tasks get queued is: |
212 // - The thread is running a message loop. | 218 // - The thread is running a message loop. |
213 // - It receives a task #1 and execute it. | 219 // - It receives a task #1 and execute it. |
214 // - The task #1 implicitly start a message loop, like a MessageBox in the | 220 // - The task #1 implicitly start a message loop, like a MessageBox in the |
215 // unit test. This can also be StartDoc or GetSaveFileName. | 221 // unit test. This can also be StartDoc or GetSaveFileName. |
216 // - The thread receives a task #2 before or while in this second message | 222 // - The thread receives a task #2 before or while in this second message |
217 // loop. | 223 // loop. |
218 // - With NestableTasksAllowed set to true, the task #2 will run right away. | 224 // - With NestableTasksAllowed set to true, the task #2 will run right away. |
219 // Otherwise, it will get executed right after task #1 completes at "thread | 225 // Otherwise, it will get executed right after task #1 completes at "thread |
220 // message loop level". | 226 // message loop level". |
221 void SetNestableTasksAllowed(bool allowed); | 227 void SetNestableTasksAllowed(bool allowed); |
222 bool NestableTasksAllowed() const; | 228 bool NestableTasksAllowed() const; |
223 | 229 |
224 // Enables or disables the restoration during an exception of the unhandled | 230 // Enables or disables the restoration during an exception of the unhandled |
225 // exception filter that was active when Run() was called. This can happen | 231 // exception filter that was active when Run() was called. This can happen |
226 // if some third party code call SetUnhandledExceptionFilter() and never | 232 // if some third party code call SetUnhandledExceptionFilter() and never |
227 // restores the previous filter. | 233 // restores the previous filter. |
228 void set_exception_restoration(bool restore) { | 234 void set_exception_restoration(bool restore) { |
229 exception_restoration_ = restore; | 235 exception_restoration_ = restore; |
230 } | 236 } |
231 | 237 |
232 | |
233 //---------------------------------------------------------------------------- | 238 //---------------------------------------------------------------------------- |
234 protected: | 239 protected: |
235 friend class base::TimerManager; // So it can call DidChangeNextTimerExpiry | |
236 | |
237 struct RunState { | 240 struct RunState { |
238 // Used to count how many Run() invocations are on the stack. | 241 // Used to count how many Run() invocations are on the stack. |
239 int run_depth; | 242 int run_depth; |
240 | 243 |
241 // Used to record that Quit() was called, or that we should quit the pump | 244 // Used to record that Quit() was called, or that we should quit the pump |
242 // once it becomes idle. | 245 // once it becomes idle. |
243 bool quit_received; | 246 bool quit_received; |
244 | 247 |
245 #if defined(OS_WIN) | 248 #if defined(OS_WIN) |
246 base::MessagePumpWin::Dispatcher* dispatcher; | 249 base::MessagePumpWin::Dispatcher* dispatcher; |
247 #endif | 250 #endif |
248 }; | 251 }; |
249 | 252 |
250 class AutoRunState : RunState { | 253 class AutoRunState : RunState { |
251 public: | 254 public: |
252 AutoRunState(MessageLoop* loop); | 255 AutoRunState(MessageLoop* loop); |
253 ~AutoRunState(); | 256 ~AutoRunState(); |
254 private: | 257 private: |
255 MessageLoop* loop_; | 258 MessageLoop* loop_; |
256 RunState* previous_state_; | 259 RunState* previous_state_; |
257 }; | 260 }; |
258 | 261 |
259 // A prioritized queue with interface that mostly matches std::queue<>. | 262 // This structure is copied around by value. |
260 // For debugging/performance testing, you can swap in std::queue<Task*>. | 263 struct PendingTask { |
261 class PrioritizedTaskQueue { | 264 Task* task; // The task to run. |
262 public: | 265 Time delayed_run_time; // The time when the task should be run. |
263 PrioritizedTaskQueue() : next_sequence_number_(0) {} | 266 int sequence_num; // Used to facilitate sorting by run time. |
264 ~PrioritizedTaskQueue() {} | 267 bool nestable; // True if OK to dispatch from a nested loop. |
265 void pop() { queue_.pop(); } | |
266 bool empty() { return queue_.empty(); } | |
267 size_t size() { return queue_.size(); } | |
268 Task* front() { return queue_.top().task(); } | |
269 void push(Task * task); | |
270 | 268 |
271 private: | 269 PendingTask(Task* task, bool nestable) |
272 class PrioritizedTask { | 270 : task(task), sequence_num(0), nestable(nestable) { |
273 public: | 271 } |
274 PrioritizedTask(Task* task, int sequence_number) | 272 |
275 : task_(task), | 273 // Used to support sorting. |
276 sequence_number_(sequence_number), | 274 bool operator<(const PendingTask& other) const; |
277 priority_(task->priority()) {} | |
278 Task* task() const { return task_; } | |
279 bool operator < (PrioritizedTask const & right) const ; | |
280 | |
281 private: | |
282 Task* task_; | |
283 // Number to ensure (default) FIFO ordering in a PriorityQueue. | |
284 int sequence_number_; | |
285 // Priority of task when pushed. | |
286 int priority_; | |
287 }; // class PrioritizedTask | |
288 | |
289 std::priority_queue<PrioritizedTask> queue_; | |
290 // Default sequence number used when push'ing (monotonically decreasing). | |
291 int next_sequence_number_; | |
292 DISALLOW_EVIL_CONSTRUCTORS(PrioritizedTaskQueue); | |
293 }; | 275 }; |
294 | 276 |
295 // Implementation of a TaskQueue as a null terminated list, with end pointers. | 277 typedef std::queue<PendingTask> TaskQueue; |
296 class TaskQueue { | 278 typedef std::priority_queue<PendingTask> DelayedTaskQueue; |
297 public: | |
298 TaskQueue() : first_(NULL), last_(NULL) {} | |
299 void Push(Task* task); | |
300 Task* Pop(); // Extract the next Task from the queue, and return it. | |
301 bool Empty() const { return !first_; } | |
302 private: | |
303 Task* first_; | |
304 Task* last_; | |
305 }; | |
306 | |
307 // Implementation of a Task queue that automatically switches into a priority | |
308 // queue if it observes any non-zero priorities in tasks. | |
309 class OptionallyPrioritizedTaskQueue { | |
310 public: | |
311 OptionallyPrioritizedTaskQueue() : use_priority_queue_(false) {} | |
312 void Push(Task* task); | |
313 Task* Pop(); // Extract next Task from queue, and return it. | |
314 bool Empty(); | |
315 bool use_priority_queue() const { return use_priority_queue_; } | |
316 | |
317 private: | |
318 bool use_priority_queue_; | |
319 PrioritizedTaskQueue prioritized_queue_; | |
320 TaskQueue queue_; | |
321 DISALLOW_EVIL_CONSTRUCTORS(OptionallyPrioritizedTaskQueue); | |
322 }; | |
323 | 279 |
324 #if defined(OS_WIN) | 280 #if defined(OS_WIN) |
325 base::MessagePumpWin* pump_win() { | 281 base::MessagePumpWin* pump_win() { |
326 return static_cast<base::MessagePumpWin*>(pump_.get()); | 282 return static_cast<base::MessagePumpWin*>(pump_.get()); |
327 } | 283 } |
328 #endif | 284 #endif |
329 | 285 |
330 // A function to encapsulate all the exception handling capability in the | 286 // A function to encapsulate all the exception handling capability in the |
331 // stacks around the running of a main message loop. It will run the message | 287 // stacks around the running of a main message loop. It will run the message |
332 // loop in a SEH try block or not depending on the set_SEH_restoration() | 288 // loop in a SEH try block or not depending on the set_SEH_restoration() |
(...skipping 16 matching lines...) Expand all Loading... |
349 // it executes a task. Queued tasks accumulate only when there is a | 305 // it executes a task. Queued tasks accumulate only when there is a |
350 // non-nestable task currently processing, in which case the new_task is | 306 // non-nestable task currently processing, in which case the new_task is |
351 // appended to the list work_queue_. Such re-entrancy generally happens when | 307 // appended to the list work_queue_. Such re-entrancy generally happens when |
352 // an unrequested message pump (typical of a native dialog) is executing in | 308 // an unrequested message pump (typical of a native dialog) is executing in |
353 // the context of a task. | 309 // the context of a task. |
354 bool QueueOrRunTask(Task* new_task); | 310 bool QueueOrRunTask(Task* new_task); |
355 | 311 |
356 // Runs the specified task and deletes it. | 312 // Runs the specified task and deletes it. |
357 void RunTask(Task* task); | 313 void RunTask(Task* task); |
358 | 314 |
359 // Make state adjustments just before and after running tasks so that we can | 315 // Calls RunTask or queues the pending_task on the deferred task list if it |
360 // continue to work if a native message loop is employed during a task. | 316 // cannot be run right now. Returns true if the task was run. |
361 void BeforeTaskRunSetup(); | 317 bool DeferOrRunPendingTask(const PendingTask& pending_task); |
362 void AfterTaskRunRestore(); | |
363 | 318 |
364 // Load tasks from the incoming_queue_ into work_queue_ if the latter is | 319 // Load tasks from the incoming_queue_ into work_queue_ if the latter is |
365 // empty. The former requires a lock to access, while the latter is directly | 320 // empty. The former requires a lock to access, while the latter is directly |
366 // accessible on this thread. | 321 // accessible on this thread. |
367 void ReloadWorkQueue(); | 322 void ReloadWorkQueue(); |
368 | 323 |
369 // Delete tasks that haven't run yet without running them. Used in the | 324 // Delete tasks that haven't run yet without running them. Used in the |
370 // destructor to make sure all the task's destructors get called. | 325 // destructor to make sure all the task's destructors get called. |
371 void DeletePendingTasks(); | 326 void DeletePendingTasks(); |
372 | 327 |
373 // Post a task to our incomming queue. | 328 // Post a task to our incomming queue. |
374 void PostTaskInternal(Task* task); | 329 void PostTask_Helper(const tracked_objects::Location& from_here, Task* task, |
375 | 330 int delay_ms, bool nestable); |
376 // Called by the TimerManager when its next timer changes. | |
377 void DidChangeNextTimerExpiry(); | |
378 | |
379 // Entry point for TimerManager to request the Run() of a task. If we | |
380 // created the task during an PostTask(FROM_HERE, ), then we will also | |
381 // perform destructions, and we'll have the option of queueing the task. If | |
382 // we didn't create the timer, then we will Run it immediately. | |
383 bool RunTimerTask(Timer* timer); | |
384 | |
385 // Since some Timer's are owned by MessageLoop, the TimerManager (when it is | |
386 // being destructed) passses us the timers to discard (without doing a Run()). | |
387 void DiscardTimer(Timer* timer); | |
388 | 331 |
389 // base::MessagePump::Delegate methods: | 332 // base::MessagePump::Delegate methods: |
390 virtual bool DoWork(); | 333 virtual bool DoWork(); |
391 virtual bool DoDelayedWork(Time* next_delayed_work_time); | 334 virtual bool DoDelayedWork(Time* next_delayed_work_time); |
392 virtual bool DoIdleWork(); | 335 virtual bool DoIdleWork(); |
393 | 336 |
394 // Start recording histogram info about events and action IF it was enabled | 337 // Start recording histogram info about events and action IF it was enabled |
395 // and IF the statistics recorder can accept a registration of our histogram. | 338 // and IF the statistics recorder can accept a registration of our histogram. |
396 void StartHistogrammer(); | 339 void StartHistogrammer(); |
397 | 340 |
398 // Add occurence of event to our histogram, so that we can see what is being | 341 // Add occurence of event to our histogram, so that we can see what is being |
399 // done in a specific MessageLoop instance (i.e., specific thread). | 342 // done in a specific MessageLoop instance (i.e., specific thread). |
400 // If message_histogram_ is NULL, this is a no-op. | 343 // If message_histogram_ is NULL, this is a no-op. |
401 void HistogramEvent(int event); | 344 void HistogramEvent(int event); |
402 | 345 |
403 static TLSSlot tls_index_; | 346 static TLSSlot tls_index_; |
404 static const LinearHistogram::DescriptionPair event_descriptions_[]; | 347 static const LinearHistogram::DescriptionPair event_descriptions_[]; |
405 static bool enable_histogrammer_; | 348 static bool enable_histogrammer_; |
406 | 349 |
407 Type type_; | 350 Type type_; |
408 | 351 |
409 base::TimerManager timer_manager_; | 352 // A list of tasks that need to be processed by this instance. Note that |
| 353 // this queue is only accessed (push/pop) by our current thread. |
| 354 TaskQueue work_queue_; |
| 355 |
| 356 // Contains delayed tasks, sorted by their 'delayed_run_time' property. |
| 357 DelayedTaskQueue delayed_work_queue_; |
410 | 358 |
411 // A list of tasks that need to be processed by this instance. Note that this | 359 // A queue of non-nestable tasks that we had to defer because when it came |
412 // queue is only accessed (push/pop) by our current thread. | 360 // time to execute them we were in a nested message loop. They will execute |
413 // As an optimization, when we don't need to use the prioritization of | 361 // once we're out of nested message loops. |
414 // work_queue_, we use a null terminated list (TaskQueue) as our | 362 TaskQueue deferred_non_nestable_work_queue_; |
415 // implementation of the queue. This saves on memory (list uses pointers | |
416 // internal to Task) and probably runs faster than the priority queue when | |
417 // there was no real prioritization. | |
418 OptionallyPrioritizedTaskQueue work_queue_; | |
419 | 363 |
420 scoped_refptr<base::MessagePump> pump_; | 364 scoped_refptr<base::MessagePump> pump_; |
421 | 365 |
422 ObserverList<DestructionObserver> destruction_observers_; | 366 ObserverList<DestructionObserver> destruction_observers_; |
423 // A recursion block that prevents accidentally running additonal tasks when | 367 // A recursion block that prevents accidentally running additonal tasks when |
424 // insider a (accidentally induced?) nested message pump. | 368 // insider a (accidentally induced?) nested message pump. |
425 bool nestable_tasks_allowed_; | 369 bool nestable_tasks_allowed_; |
426 | 370 |
427 bool exception_restoration_; | 371 bool exception_restoration_; |
428 | 372 |
429 std::string thread_name_; | 373 std::string thread_name_; |
430 // A profiling histogram showing the counts of various messages and events. | 374 // A profiling histogram showing the counts of various messages and events. |
431 scoped_ptr<LinearHistogram> message_histogram_; | 375 scoped_ptr<LinearHistogram> message_histogram_; |
432 | 376 |
433 // A null terminated list which creates an incoming_queue of tasks that are | 377 // A null terminated list which creates an incoming_queue of tasks that are |
434 // aquired under a mutex for processing on this instance's thread. These tasks | 378 // aquired under a mutex for processing on this instance's thread. These tasks |
435 // have not yet been sorted out into items for our work_queue_ vs items that | 379 // have not yet been sorted out into items for our work_queue_ vs items that |
436 // will be handled by the TimerManager. | 380 // will be handled by the TimerManager. |
437 TaskQueue incoming_queue_; | 381 TaskQueue incoming_queue_; |
438 // Protect access to incoming_queue_. | 382 // Protect access to incoming_queue_. |
439 Lock incoming_queue_lock_; | 383 Lock incoming_queue_lock_; |
440 | 384 |
441 // A null terminated list of non-nestable tasks that we had to delay because | 385 RunState* state_; |
442 // when it came time to execute them we were in a nested message loop. They | |
443 // will execute once we're out of nested message loops. | |
444 TaskQueue delayed_non_nestable_queue_; | |
445 | 386 |
446 RunState* state_; | 387 // The next sequence number to use for delayed tasks. |
| 388 int next_sequence_num_; |
447 | 389 |
448 DISALLOW_COPY_AND_ASSIGN(MessageLoop); | 390 DISALLOW_COPY_AND_ASSIGN(MessageLoop); |
449 }; | 391 }; |
450 | 392 |
451 //----------------------------------------------------------------------------- | 393 //----------------------------------------------------------------------------- |
452 // MessageLoopForUI extends MessageLoop with methods that are particular to a | 394 // MessageLoopForUI extends MessageLoop with methods that are particular to a |
453 // MessageLoop instantiated with TYPE_UI. | 395 // MessageLoop instantiated with TYPE_UI. |
454 // | 396 // |
455 // This class is typically used like so: | 397 // This class is typically used like so: |
456 // MessageLoopForUI::current()->...call some method... | 398 // MessageLoopForUI::current()->...call some method... |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 #endif // defined(OS_WIN) | 456 #endif // defined(OS_WIN) |
515 }; | 457 }; |
516 | 458 |
517 // Do not add any member variables to MessageLoopForIO! This is important b/c | 459 // Do not add any member variables to MessageLoopForIO! This is important b/c |
518 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra | 460 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra |
519 // data that you need should be stored on the MessageLoop's pump_ instance. | 461 // data that you need should be stored on the MessageLoop's pump_ instance. |
520 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), | 462 COMPILE_ASSERT(sizeof(MessageLoop) == sizeof(MessageLoopForIO), |
521 MessageLoopForIO_should_not_have_extra_member_variables); | 463 MessageLoopForIO_should_not_have_extra_member_variables); |
522 | 464 |
523 #endif // BASE_MESSAGE_LOOP_H_ | 465 #endif // BASE_MESSAGE_LOOP_H_ |
OLD | NEW |