Merge mozilla-central to autoland on a CLOSED TREE
[gecko.git] / ipc / glue / MessagePump_mac.mm
blob2af0e072038cc1741aa39007c9559e0b654e9aeb
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "MessagePump.h"
9 #include <Foundation/Foundation.h>
11 #include "base/scoped_nsautorelease_pool.h"
12 #include "mozilla/ProfilerMarkers.h"
13 #include "nsISupportsImpl.h"
15 using namespace mozilla::ipc;
17 static void NoOp(void* info) {}
19 NS_IMPL_ADDREF_INHERITED(MessagePumpForNonMainUIThreads, MessagePump)
20 NS_IMPL_RELEASE_INHERITED(MessagePumpForNonMainUIThreads, MessagePump)
21 NS_IMPL_QUERY_INTERFACE(MessagePumpForNonMainUIThreads, nsIThreadObserver)
23 MessagePumpForNonMainUIThreads::MessagePumpForNonMainUIThreads(nsISerialEventTarget* aEventTarget)
24     : mEventTarget(aEventTarget), keep_running_(true) {
25   MOZ_ASSERT(mEventTarget);
26   CFRunLoopSourceContext source_context = CFRunLoopSourceContext();
27   source_context.perform = NoOp;
28   quit_source_ = CFRunLoopSourceCreate(nullptr,  // allocator
29                                        0,        // priority
30                                        &source_context);
31   CFRunLoopAddSource(run_loop(), quit_source_, kCFRunLoopCommonModes);
34 MessagePumpForNonMainUIThreads::~MessagePumpForNonMainUIThreads() {
35   CFRunLoopRemoveSource(run_loop(), quit_source_, kCFRunLoopCommonModes);
36   CFRelease(quit_source_);
39 void MessagePumpForNonMainUIThreads::DoRun(base::MessagePump::Delegate* aDelegate) {
40   // If this is a chromium thread and no nsThread is associated with it, this call will create a
41   // new nsThread.
42   nsIThread* thread = NS_GetCurrentThread();
43   MOZ_ASSERT(thread);
45   // Set the main thread observer so we can wake up when xpcom events need to get processed.
46   nsCOMPtr<nsIThreadInternal> ti(do_QueryInterface(thread));
47   MOZ_ASSERT(ti);
48   ti->SetObserver(this);
50   base::ScopedNSAutoreleasePool autoReleasePool;
52   while (keep_running_) {
53     // Drain the xpcom event loop first.
54     if (NS_ProcessNextEvent(nullptr, false)) {
55       continue;
56     }
58     autoReleasePool.Recycle();
60     if (!keep_running_) {
61       break;
62     }
64     // Now process the CFRunLoop. It exits after running once.
65     // NSRunLoop manages autorelease pools itself.
66     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
67   }
69   ti->SetObserver(nullptr);
70   keep_running_ = true;
73 void MessagePumpForNonMainUIThreads::Quit() {
74   keep_running_ = false;
75   CFRunLoopSourceSignal(quit_source_);
76   CFRunLoopWakeUp(run_loop());
79 NS_IMETHODIMP MessagePumpForNonMainUIThreads::OnDispatchedEvent() {
80   // ScheduleWork will signal an input source to the run loop, making it exit so it can process the
81   // xpcom event.
82   ScheduleWork();
83   return NS_OK;
86 NS_IMETHODIMP
87 MessagePumpForNonMainUIThreads::OnProcessNextEvent(nsIThreadInternal* thread, bool mayWait) {
88   return NS_OK;
91 NS_IMETHODIMP
92 MessagePumpForNonMainUIThreads::AfterProcessNextEvent(nsIThreadInternal* thread,
93                                                       bool eventWasProcessed) {
94   return NS_OK;