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