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 3 // found in the LICENSE file. 4 5 #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 6 #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 7 8 #include <memory> 9 #include <queue> 10 #include <string> 11 12 #include "base/base_export.h" 13 #include "base/callback_forward.h" 14 #include "base/debug/task_annotator.h" 15 #include "base/gtest_prod_util.h" 16 #include "base/location.h" 17 #include "base/macros.h" 18 #include "base/memory/ref_counted.h" 19 #include "base/message_loop/incoming_task_queue.h" 20 #include "base/message_loop/message_loop_task_runner.h" 21 #include "base/message_loop/message_pump.h" 22 #include "base/message_loop/timer_slack.h" 23 #include "base/observer_list.h" 24 #include "base/pending_task.h" 25 #include "base/sequenced_task_runner_helpers.h" 26 #include "base/synchronization/lock.h" 27 #include "base/time/time.h" 28 #include "base/tracking_info.h" 29 #include "build/build_config.h" 30 31 // TODO(sky): these includes should not be necessary. Nuke them. 32 #if defined(OS_WIN) 33 #include "base/message_loop/message_pump_win.h" 34 #elif defined(OS_IOS) 35 #include "base/message_loop/message_pump_io_ios.h" 36 #elif defined(OS_POSIX) 37 #include "base/message_loop/message_pump_libevent.h" 38 #endif 39 40 namespace base { 41 42 class HistogramBase; 43 class RunLoop; 44 class ThreadTaskRunnerHandle; 45 class WaitableEvent; 46 47 // A MessageLoop is used to process events for a particular thread. There is 48 // at most one MessageLoop instance per thread. 49 // 50 // Events include at a minimum Task instances submitted to PostTask and its 51 // variants. Depending on the type of message pump used by the MessageLoop 52 // other events such as UI messages may be processed. On Windows APC calls (as 53 // time permits) and signals sent to a registered set of HANDLEs may also be 54 // processed. 55 // 56 // NOTE: Unless otherwise specified, a MessageLoop's methods may only be called 57 // on the thread where the MessageLoop's Run method executes. 58 // 59 // NOTE: MessageLoop has task reentrancy protection. This means that if a 60 // task is being processed, a second task cannot start until the first task is 61 // finished. Reentrancy can happen when processing a task, and an inner 62 // message pump is created. That inner pump then processes native messages 63 // which could implicitly start an inner task. Inner message pumps are created 64 // with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions 65 // (DoDragDrop), printer functions (StartDoc) and *many* others. 66 // 67 // Sample workaround when inner task processing is needed: 68 // HRESULT hr; 69 // { 70 // MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); 71 // hr = DoDragDrop(...); // Implicitly runs a modal message loop. 72 // } 73 // // Process |hr| (the result returned by DoDragDrop()). 74 // 75 // Please be SURE your task is reentrant (nestable) and all global variables 76 // are stable and accessible before calling SetNestableTasksAllowed(true). 77 // 78 class BASE_EXPORT MessageLoop : public MessagePump::Delegate { 79 public: 80 // A MessageLoop has a particular type, which indicates the set of 81 // asynchronous events it may process in addition to tasks and timers. 82 // 83 // TYPE_DEFAULT 84 // This type of ML only supports tasks and timers. 85 // 86 // TYPE_UI 87 // This type of ML also supports native UI events (e.g., Windows messages). 88 // See also MessageLoopForUI. 89 // 90 // TYPE_IO 91 // This type of ML also supports asynchronous IO. See also 92 // MessageLoopForIO. 93 // 94 // TYPE_JAVA 95 // This type of ML is backed by a Java message handler which is responsible 96 // for running the tasks added to the ML. This is only for use on Android. 97 // TYPE_JAVA behaves in essence like TYPE_UI, except during construction 98 // where it does not use the main thread specific pump factory. 99 // 100 // TYPE_CUSTOM 101 // MessagePump was supplied to constructor. 102 // 103 enum Type { 104 TYPE_DEFAULT, 105 TYPE_UI, 106 TYPE_CUSTOM, 107 TYPE_IO, 108 #if defined(OS_ANDROID) 109 TYPE_JAVA, 110 #endif // defined(OS_ANDROID) 111 }; 112 113 // Normally, it is not necessary to instantiate a MessageLoop. Instead, it 114 // is typical to make use of the current thread's MessageLoop instance. 115 explicit MessageLoop(Type type = TYPE_DEFAULT); 116 // Creates a TYPE_CUSTOM MessageLoop with the supplied MessagePump, which must 117 // be non-NULL. 118 explicit MessageLoop(std::unique_ptr<MessagePump> pump); 119 120 ~MessageLoop() override; 121 122 // Returns the MessageLoop object for the current thread, or null if none. 123 static MessageLoop* current(); 124 125 static void EnableHistogrammer(bool enable_histogrammer); 126 127 typedef std::unique_ptr<MessagePump>(MessagePumpFactory)(); 128 // Uses the given base::MessagePumpForUIFactory to override the default 129 // MessagePump implementation for 'TYPE_UI'. Returns true if the factory 130 // was successfully registered. 131 static bool InitMessagePumpForUIFactory(MessagePumpFactory* factory); 132 133 // Creates the default MessagePump based on |type|. Caller owns return 134 // value. 135 static std::unique_ptr<MessagePump> CreateMessagePumpForType(Type type); 136 137 // A DestructionObserver is notified when the current MessageLoop is being 138 // destroyed. These observers are notified prior to MessageLoop::current() 139 // being changed to return NULL. This gives interested parties the chance to 140 // do final cleanup that depends on the MessageLoop. 141 // 142 // NOTE: Any tasks posted to the MessageLoop during this notification will 143 // not be run. Instead, they will be deleted. 144 // 145 class BASE_EXPORT DestructionObserver { 146 public: 147 virtual void WillDestroyCurrentMessageLoop() = 0; 148 149 protected: 150 virtual ~DestructionObserver(); 151 }; 152 153 // Add a DestructionObserver, which will start receiving notifications 154 // immediately. 155 void AddDestructionObserver(DestructionObserver* destruction_observer); 156 157 // Remove a DestructionObserver. It is safe to call this method while a 158 // DestructionObserver is receiving a notification callback. 159 void RemoveDestructionObserver(DestructionObserver* destruction_observer); 160 161 // A NestingObserver is notified when a nested message loop begins. The 162 // observers are notified before the first task is processed. 163 class BASE_EXPORT NestingObserver { 164 public: 165 virtual void OnBeginNestedMessageLoop() = 0; 166 167 protected: 168 virtual ~NestingObserver(); 169 }; 170 171 void AddNestingObserver(NestingObserver* observer); 172 void RemoveNestingObserver(NestingObserver* observer); 173 174 // NOTE: Deprecated; prefer task_runner() and the TaskRunner interfaces. 175 // TODO(skyostil): Remove these functions (crbug.com/465354). 176 // 177 // The "PostTask" family of methods call the task's Run method asynchronously 178 // from within a message loop at some point in the future. 179 // 180 // With the PostTask variant, tasks are invoked in FIFO order, inter-mixed 181 // with normal UI or IO event processing. With the PostDelayedTask variant, 182 // tasks are called after at least approximately 'delay_ms' have elapsed. 183 // 184 // The NonNestable variants work similarly except that they promise never to 185 // dispatch the task from a nested invocation of MessageLoop::Run. Instead, 186 // such tasks get deferred until the top-most MessageLoop::Run is executing. 187 // 188 // The MessageLoop takes ownership of the Task, and deletes it after it has 189 // been Run(). 190 // 191 // PostTask(from_here, task) is equivalent to 192 // PostDelayedTask(from_here, task, 0). 193 // 194 // NOTE: These methods may be called on any thread. The Task will be invoked 195 // on the thread that executes MessageLoop::Run(). 196 void PostTask(const tracked_objects::Location& from_here, 197 const Closure& task); 198 199 void PostDelayedTask(const tracked_objects::Location& from_here, 200 const Closure& task, 201 TimeDelta delay); 202 203 // A variant on PostTask that deletes the given object. This is useful 204 // if the object needs to live until the next run of the MessageLoop (for 205 // example, deleting a RenderProcessHost from within an IPC callback is not 206 // good). 207 // 208 // NOTE: This method may be called on any thread. The object will be deleted 209 // on the thread that executes MessageLoop::Run(). 210 template <class T> DeleteSoon(const tracked_objects::Location & from_here,const T * object)211 void DeleteSoon(const tracked_objects::Location& from_here, const T* object) { 212 base::subtle::DeleteHelperInternal<T, void>::DeleteViaSequencedTaskRunner( 213 this, from_here, object); 214 } 215 216 // A variant on PostTask that releases the given reference counted object 217 // (by calling its Release method). This is useful if the object needs to 218 // live until the next run of the MessageLoop, or if the object needs to be 219 // released on a particular thread. 220 // 221 // A common pattern is to manually increment the object's reference count 222 // (AddRef), clear the pointer, then issue a ReleaseSoon. The reference count 223 // is incremented manually to ensure clearing the pointer does not trigger a 224 // delete and to account for the upcoming decrement (ReleaseSoon). For 225 // example: 226 // 227 // scoped_refptr<Foo> foo = ... 228 // foo->AddRef(); 229 // Foo* raw_foo = foo.get(); 230 // foo = NULL; 231 // message_loop->ReleaseSoon(raw_foo); 232 // 233 // NOTE: This method may be called on any thread. The object will be 234 // released (and thus possibly deleted) on the thread that executes 235 // MessageLoop::Run(). If this is not the same as the thread that calls 236 // ReleaseSoon(FROM_HERE, ), then T MUST inherit from 237 // RefCountedThreadSafe<T>! 238 template <class T> ReleaseSoon(const tracked_objects::Location & from_here,const T * object)239 void ReleaseSoon(const tracked_objects::Location& from_here, 240 const T* object) { 241 base::subtle::ReleaseHelperInternal<T, void>::ReleaseViaSequencedTaskRunner( 242 this, from_here, object); 243 } 244 245 // Deprecated: use RunLoop instead. 246 // Run the message loop. 247 void Run(); 248 249 // Deprecated: use RunLoop instead. 250 // Process all pending tasks, windows messages, etc., but don't wait/sleep. 251 // Return as soon as all items that can be run are taken care of. 252 void RunUntilIdle(); 253 254 // Deprecated: use RunLoop instead. 255 // 256 // Signals the Run method to return when it becomes idle. It will continue to 257 // process pending messages and future messages as long as they are enqueued. 258 // Warning: if the MessageLoop remains busy, it may never quit. Only use this 259 // Quit method when looping procedures (such as web pages) have been shut 260 // down. 261 // 262 // This method may only be called on the same thread that called Run, and Run 263 // must still be on the call stack. 264 // 265 // Use QuitClosure variants if you need to Quit another thread's MessageLoop, 266 // but note that doing so is fairly dangerous if the target thread makes 267 // nested calls to MessageLoop::Run. The problem being that you won't know 268 // which nested run loop you are quitting, so be careful! 269 void QuitWhenIdle(); 270 271 // Deprecated: use RunLoop instead. 272 // 273 // This method is a variant of Quit, that does not wait for pending messages 274 // to be processed before returning from Run. 275 void QuitNow(); 276 277 // Deprecated: use RunLoop instead. 278 // Construct a Closure that will call QuitWhenIdle(). Useful to schedule an 279 // arbitrary MessageLoop to QuitWhenIdle. 280 static Closure QuitWhenIdleClosure(); 281 282 // Set the timer slack for this message loop. SetTimerSlack(TimerSlack timer_slack)283 void SetTimerSlack(TimerSlack timer_slack) { 284 pump_->SetTimerSlack(timer_slack); 285 } 286 287 // Returns true if this loop is |type|. This allows subclasses (especially 288 // those in tests) to specialize how they are identified. 289 virtual bool IsType(Type type) const; 290 291 // Returns the type passed to the constructor. type()292 Type type() const { return type_; } 293 294 // Returns the name of the thread this message loop is bound to. 295 // This function is only valid when this message loop is running and 296 // BindToCurrentThread has already been called. 297 std::string GetThreadName() const; 298 299 // Gets the TaskRunner associated with this message loop. task_runner()300 const scoped_refptr<SingleThreadTaskRunner>& task_runner() { 301 return task_runner_; 302 } 303 304 // Sets a new TaskRunner for this message loop. The message loop must already 305 // have been bound to a thread prior to this call, and the task runner must 306 // belong to that thread. Note that changing the task runner will also affect 307 // the ThreadTaskRunnerHandle for the target thread. Must be called on the 308 // thread to which the message loop is bound. 309 void SetTaskRunner(scoped_refptr<SingleThreadTaskRunner> task_runner); 310 311 // Enables or disables the recursive task processing. This happens in the case 312 // of recursive message loops. Some unwanted message loops may occur when 313 // using common controls or printer functions. By default, recursive task 314 // processing is disabled. 315 // 316 // Please use |ScopedNestableTaskAllower| instead of calling these methods 317 // directly. In general, nestable message loops are to be avoided. They are 318 // dangerous and difficult to get right, so please use with extreme caution. 319 // 320 // The specific case where tasks get queued is: 321 // - The thread is running a message loop. 322 // - It receives a task #1 and executes it. 323 // - The task #1 implicitly starts a message loop, like a MessageBox in the 324 // unit test. This can also be StartDoc or GetSaveFileName. 325 // - The thread receives a task #2 before or while in this second message 326 // loop. 327 // - With NestableTasksAllowed set to true, the task #2 will run right away. 328 // Otherwise, it will get executed right after task #1 completes at "thread 329 // message loop level". 330 void SetNestableTasksAllowed(bool allowed); 331 bool NestableTasksAllowed() const; 332 333 // Enables nestable tasks on |loop| while in scope. 334 class ScopedNestableTaskAllower { 335 public: ScopedNestableTaskAllower(MessageLoop * loop)336 explicit ScopedNestableTaskAllower(MessageLoop* loop) 337 : loop_(loop), 338 old_state_(loop_->NestableTasksAllowed()) { 339 loop_->SetNestableTasksAllowed(true); 340 } ~ScopedNestableTaskAllower()341 ~ScopedNestableTaskAllower() { 342 loop_->SetNestableTasksAllowed(old_state_); 343 } 344 345 private: 346 MessageLoop* loop_; 347 bool old_state_; 348 }; 349 350 // Returns true if we are currently running a nested message loop. 351 bool IsNested(); 352 353 // A TaskObserver is an object that receives task notifications from the 354 // MessageLoop. 355 // 356 // NOTE: A TaskObserver implementation should be extremely fast! 357 class BASE_EXPORT TaskObserver { 358 public: 359 TaskObserver(); 360 361 // This method is called before processing a task. 362 virtual void WillProcessTask(const PendingTask& pending_task) = 0; 363 364 // This method is called after processing a task. 365 virtual void DidProcessTask(const PendingTask& pending_task) = 0; 366 367 protected: 368 virtual ~TaskObserver(); 369 }; 370 371 // These functions can only be called on the same thread that |this| is 372 // running on. 373 void AddTaskObserver(TaskObserver* task_observer); 374 void RemoveTaskObserver(TaskObserver* task_observer); 375 376 // Can only be called from the thread that owns the MessageLoop. 377 bool is_running() const; 378 379 // Returns true if the message loop has high resolution timers enabled. 380 // Provided for testing. 381 bool HasHighResolutionTasks(); 382 383 // Returns true if the message loop is "idle". Provided for testing. 384 bool IsIdleForTesting(); 385 386 // Returns the TaskAnnotator which is used to add debug information to posted 387 // tasks. task_annotator()388 debug::TaskAnnotator* task_annotator() { return &task_annotator_; } 389 390 // Runs the specified PendingTask. 391 void RunTask(const PendingTask& pending_task); 392 393 #if defined(OS_WIN) 394 // TODO (stanisc): crbug.com/596190: Remove this after the signaling issue 395 // has been investigated. 396 // This should be used for diagnostic only. If message pump wake-up mechanism 397 // is based on auto-reset event this call would reset the event to unset 398 // state. 399 bool MessagePumpWasSignaled(); 400 #endif 401 402 //---------------------------------------------------------------------------- 403 protected: 404 std::unique_ptr<MessagePump> pump_; 405 406 using MessagePumpFactoryCallback = Callback<std::unique_ptr<MessagePump>()>; 407 408 // Common protected constructor. Other constructors delegate the 409 // initialization to this constructor. 410 // A subclass can invoke this constructor to create a message_loop of a 411 // specific type with a custom loop. The implementation does not call 412 // BindToCurrentThread. If this constructor is invoked directly by a subclass, 413 // then the subclass must subsequently bind the message loop. 414 MessageLoop(Type type, MessagePumpFactoryCallback pump_factory); 415 416 // Configure various members and bind this message loop to the current thread. 417 void BindToCurrentThread(); 418 419 private: 420 friend class RunLoop; 421 friend class internal::IncomingTaskQueue; 422 friend class ScheduleWorkTest; 423 friend class Thread; 424 FRIEND_TEST_ALL_PREFIXES(MessageLoopTest, DeleteUnboundLoop); 425 426 // Creates a MessageLoop without binding to a thread. 427 // If |type| is TYPE_CUSTOM non-null |pump_factory| must be also given 428 // to create a message pump for this message loop. Otherwise a default 429 // message pump for the |type| is created. 430 // 431 // It is valid to call this to create a new message loop on one thread, 432 // and then pass it to the thread where the message loop actually runs. 433 // The message loop's BindToCurrentThread() method must be called on the 434 // thread the message loop runs on, before calling Run(). 435 // Before BindToCurrentThread() is called, only Post*Task() functions can 436 // be called on the message loop. 437 static std::unique_ptr<MessageLoop> CreateUnbound( 438 Type type, 439 MessagePumpFactoryCallback pump_factory); 440 441 // Sets the ThreadTaskRunnerHandle for the current thread to point to the 442 // task runner for this message loop. 443 void SetThreadTaskRunnerHandle(); 444 445 // Invokes the actual run loop using the message pump. 446 void RunHandler(); 447 448 // Called to process any delayed non-nestable tasks. 449 bool ProcessNextDelayedNonNestableTask(); 450 451 // Calls RunTask or queues the pending_task on the deferred task list if it 452 // cannot be run right now. Returns true if the task was run. 453 bool DeferOrRunPendingTask(PendingTask pending_task); 454 455 // Adds the pending task to delayed_work_queue_. 456 void AddToDelayedWorkQueue(PendingTask pending_task); 457 458 // Delete tasks that haven't run yet without running them. Used in the 459 // destructor to make sure all the task's destructors get called. Returns 460 // true if some work was done. 461 bool DeletePendingTasks(); 462 463 // Loads tasks from the incoming queue to |work_queue_| if the latter is 464 // empty. 465 void ReloadWorkQueue(); 466 467 // Wakes up the message pump. Can be called on any thread. The caller is 468 // responsible for synchronizing ScheduleWork() calls. 469 void ScheduleWork(); 470 471 // Start recording histogram info about events and action IF it was enabled 472 // and IF the statistics recorder can accept a registration of our histogram. 473 void StartHistogrammer(); 474 475 // Add occurrence of event to our histogram, so that we can see what is being 476 // done in a specific MessageLoop instance (i.e., specific thread). 477 // If message_histogram_ is NULL, this is a no-op. 478 void HistogramEvent(int event); 479 480 // Notify observers that a nested message loop is starting. 481 void NotifyBeginNestedLoop(); 482 483 // MessagePump::Delegate methods: 484 bool DoWork() override; 485 bool DoDelayedWork(TimeTicks* next_delayed_work_time) override; 486 bool DoIdleWork() override; 487 488 const Type type_; 489 490 // A list of tasks that need to be processed by this instance. Note that 491 // this queue is only accessed (push/pop) by our current thread. 492 TaskQueue work_queue_; 493 494 #if defined(OS_WIN) 495 // How many high resolution tasks are in the pending task queue. This value 496 // increases by N every time we call ReloadWorkQueue() and decreases by 1 497 // every time we call RunTask() if the task needs a high resolution timer. 498 int pending_high_res_tasks_; 499 // Tracks if we have requested high resolution timers. Its only use is to 500 // turn off the high resolution timer upon loop destruction. 501 bool in_high_res_mode_; 502 #endif 503 504 // Contains delayed tasks, sorted by their 'delayed_run_time' property. 505 DelayedTaskQueue delayed_work_queue_; 506 507 // A recent snapshot of Time::Now(), used to check delayed_work_queue_. 508 TimeTicks recent_time_; 509 510 // A queue of non-nestable tasks that we had to defer because when it came 511 // time to execute them we were in a nested message loop. They will execute 512 // once we're out of nested message loops. 513 TaskQueue deferred_non_nestable_work_queue_; 514 515 ObserverList<DestructionObserver> destruction_observers_; 516 517 ObserverList<NestingObserver> nesting_observers_; 518 519 // A recursion block that prevents accidentally running additional tasks when 520 // insider a (accidentally induced?) nested message pump. 521 bool nestable_tasks_allowed_; 522 523 // pump_factory_.Run() is called to create a message pump for this loop 524 // if type_ is TYPE_CUSTOM and pump_ is null. 525 MessagePumpFactoryCallback pump_factory_; 526 527 // A profiling histogram showing the counts of various messages and events. 528 HistogramBase* message_histogram_; 529 530 RunLoop* run_loop_; 531 532 ObserverList<TaskObserver> task_observers_; 533 534 debug::TaskAnnotator task_annotator_; 535 536 scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_; 537 538 // A task runner which we haven't bound to a thread yet. 539 scoped_refptr<internal::MessageLoopTaskRunner> unbound_task_runner_; 540 541 // The task runner associated with this message loop. 542 scoped_refptr<SingleThreadTaskRunner> task_runner_; 543 std::unique_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_; 544 545 // Id of the thread this message loop is bound to. 546 PlatformThreadId thread_id_; 547 548 template <class T, class R> friend class base::subtle::DeleteHelperInternal; 549 template <class T, class R> friend class base::subtle::ReleaseHelperInternal; 550 551 void DeleteSoonInternal(const tracked_objects::Location& from_here, 552 void(*deleter)(const void*), 553 const void* object); 554 void ReleaseSoonInternal(const tracked_objects::Location& from_here, 555 void(*releaser)(const void*), 556 const void* object); 557 558 DISALLOW_COPY_AND_ASSIGN(MessageLoop); 559 }; 560 561 #if !defined(OS_NACL) 562 563 //----------------------------------------------------------------------------- 564 // MessageLoopForUI extends MessageLoop with methods that are particular to a 565 // MessageLoop instantiated with TYPE_UI. 566 // 567 // This class is typically used like so: 568 // MessageLoopForUI::current()->...call some method... 569 // 570 class BASE_EXPORT MessageLoopForUI : public MessageLoop { 571 public: MessageLoopForUI()572 MessageLoopForUI() : MessageLoop(TYPE_UI) { 573 } 574 575 explicit MessageLoopForUI(std::unique_ptr<MessagePump> pump); 576 577 // Returns the MessageLoopForUI of the current thread. current()578 static MessageLoopForUI* current() { 579 MessageLoop* loop = MessageLoop::current(); 580 DCHECK(loop); 581 DCHECK(loop->IsType(MessageLoop::TYPE_UI)); 582 return static_cast<MessageLoopForUI*>(loop); 583 } 584 IsCurrent()585 static bool IsCurrent() { 586 MessageLoop* loop = MessageLoop::current(); 587 return loop && loop->IsType(MessageLoop::TYPE_UI); 588 } 589 590 #if defined(OS_IOS) 591 // On iOS, the main message loop cannot be Run(). Instead call Attach(), 592 // which connects this MessageLoop to the UI thread's CFRunLoop and allows 593 // PostTask() to work. 594 void Attach(); 595 #endif 596 597 #if defined(OS_ANDROID) 598 // On Android, the UI message loop is handled by Java side. So Run() should 599 // never be called. Instead use Start(), which will forward all the native UI 600 // events to the Java message loop. 601 void Start(); 602 #endif 603 604 #if defined(USE_OZONE) || (defined(USE_X11) && !defined(USE_GLIB)) 605 // Please see MessagePumpLibevent for definition. 606 bool WatchFileDescriptor( 607 int fd, 608 bool persistent, 609 MessagePumpLibevent::Mode mode, 610 MessagePumpLibevent::FileDescriptorWatcher* controller, 611 MessagePumpLibevent::Watcher* delegate); 612 #endif 613 }; 614 615 // Do not add any member variables to MessageLoopForUI! This is important b/c 616 // MessageLoopForUI is often allocated via MessageLoop(TYPE_UI). Any extra 617 // data that you need should be stored on the MessageLoop's pump_ instance. 618 static_assert(sizeof(MessageLoop) == sizeof(MessageLoopForUI), 619 "MessageLoopForUI should not have extra member variables"); 620 621 #endif // !defined(OS_NACL) 622 623 //----------------------------------------------------------------------------- 624 // MessageLoopForIO extends MessageLoop with methods that are particular to a 625 // MessageLoop instantiated with TYPE_IO. 626 // 627 // This class is typically used like so: 628 // MessageLoopForIO::current()->...call some method... 629 // 630 class BASE_EXPORT MessageLoopForIO : public MessageLoop { 631 public: 632 MessageLoopForIO(); 633 634 // Returns the MessageLoopForIO of the current thread. current()635 static MessageLoopForIO* current() { 636 MessageLoop* loop = MessageLoop::current(); 637 DCHECK(loop) << "Can't call MessageLoopForIO::current() when no message " 638 "loop was created for this thread. Use " 639 " MessageLoop::current() or MessageLoopForIO::IsCurrent()."; 640 DCHECK_EQ(MessageLoop::TYPE_IO, loop->type()); 641 return static_cast<MessageLoopForIO*>(loop); 642 } 643 IsCurrent()644 static bool IsCurrent() { 645 MessageLoop* loop = MessageLoop::current(); 646 return loop && loop->type() == MessageLoop::TYPE_IO; 647 } 648 649 #if !defined(OS_NACL_SFI) 650 651 #if defined(OS_WIN) 652 typedef MessagePumpForIO::IOHandler IOHandler; 653 typedef MessagePumpForIO::IOContext IOContext; 654 #elif defined(OS_IOS) 655 typedef MessagePumpIOSForIO::Watcher Watcher; 656 typedef MessagePumpIOSForIO::FileDescriptorWatcher 657 FileDescriptorWatcher; 658 659 enum Mode { 660 WATCH_READ = MessagePumpIOSForIO::WATCH_READ, 661 WATCH_WRITE = MessagePumpIOSForIO::WATCH_WRITE, 662 WATCH_READ_WRITE = MessagePumpIOSForIO::WATCH_READ_WRITE 663 }; 664 #elif defined(OS_POSIX) 665 typedef MessagePumpLibevent::Watcher Watcher; 666 typedef MessagePumpLibevent::FileDescriptorWatcher 667 FileDescriptorWatcher; 668 669 enum Mode { 670 WATCH_READ = MessagePumpLibevent::WATCH_READ, 671 WATCH_WRITE = MessagePumpLibevent::WATCH_WRITE, 672 WATCH_READ_WRITE = MessagePumpLibevent::WATCH_READ_WRITE 673 }; 674 #endif 675 676 #if defined(OS_WIN) 677 // Please see MessagePumpWin for definitions of these methods. 678 void RegisterIOHandler(HANDLE file, IOHandler* handler); 679 bool RegisterJobObject(HANDLE job, IOHandler* handler); 680 bool WaitForIOCompletion(DWORD timeout, IOHandler* filter); 681 #elif defined(OS_POSIX) 682 // Please see MessagePumpIOSForIO/MessagePumpLibevent for definition. 683 bool WatchFileDescriptor(int fd, 684 bool persistent, 685 Mode mode, 686 FileDescriptorWatcher* controller, 687 Watcher* delegate); 688 #endif // defined(OS_IOS) || defined(OS_POSIX) 689 #endif // !defined(OS_NACL_SFI) 690 }; 691 692 // Do not add any member variables to MessageLoopForIO! This is important b/c 693 // MessageLoopForIO is often allocated via MessageLoop(TYPE_IO). Any extra 694 // data that you need should be stored on the MessageLoop's pump_ instance. 695 static_assert(sizeof(MessageLoop) == sizeof(MessageLoopForIO), 696 "MessageLoopForIO should not have extra member variables"); 697 698 } // namespace base 699 700 #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_H_ 701