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
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
42 nsIThread* thread = NS_GetCurrentThread();
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));
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)) {
58 autoReleasePool.Recycle();
64 // Now process the CFRunLoop. It exits after running once.
65 // NSRunLoop manages autorelease pools itself.
66 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
69 ti->SetObserver(nullptr);
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
87 MessagePumpForNonMainUIThreads::OnProcessNextEvent(nsIThreadInternal* thread, bool mayWait) {
92 MessagePumpForNonMainUIThreads::AfterProcessNextEvent(nsIThreadInternal* thread,
93 bool eventWasProcessed) {