MessagePump.h (5783B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=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/. */ 6 7 #ifndef __IPC_GLUE_MESSAGEPUMP_H__ 8 #define __IPC_GLUE_MESSAGEPUMP_H__ 9 10 #include "base/message_pump_default.h" 11 #if defined(XP_WIN) 12 # include "base/message_pump_win.h" 13 #elif defined(XP_DARWIN) 14 # include "base/message_pump_mac.h" 15 #endif 16 17 #include "base/time.h" 18 #include "mozilla/Mutex.h" 19 #include "nsCOMPtr.h" 20 #include "nsIThreadInternal.h" 21 22 class nsIEventTarget; 23 class nsITimer; 24 25 namespace mozilla { 26 namespace ipc { 27 28 class DoWorkRunnable; 29 30 class MessagePump : public base::MessagePumpDefault { 31 friend class DoWorkRunnable; 32 33 public: 34 explicit MessagePump(nsISerialEventTarget* aEventTarget); 35 36 // From base::MessagePump. 37 virtual void Run(base::MessagePump::Delegate* aDelegate) override; 38 39 // From base::MessagePump. 40 virtual void ScheduleWork() override; 41 42 // From base::MessagePump. 43 virtual void ScheduleWorkForNestedLoop() override; 44 45 // From base::MessagePump. 46 virtual void ScheduleDelayedWork( 47 const base::TimeTicks& aDelayedWorkTime) override; 48 49 virtual nsISerialEventTarget* GetXPCOMThread() override; 50 51 protected: 52 virtual ~MessagePump(); 53 54 private: 55 // Only called by DoWorkRunnable. 56 void DoDelayedWork(base::MessagePump::Delegate* aDelegate); 57 58 protected: 59 nsISerialEventTarget* mEventTarget; 60 61 // mDelayedWorkTimer and mEventTarget are set in Run() by this class or its 62 // subclasses. 63 nsCOMPtr<nsITimer> mDelayedWorkTimer; 64 65 private: 66 // Only accessed by this class. 67 RefPtr<DoWorkRunnable> mDoWorkEvent; 68 }; 69 70 class MessagePumpForChildProcess final : public MessagePump { 71 public: 72 MessagePumpForChildProcess() : MessagePump(nullptr), mFirstRun(true) {} 73 74 virtual void Run(base::MessagePump::Delegate* aDelegate) override; 75 76 private: 77 ~MessagePumpForChildProcess() = default; 78 79 bool mFirstRun; 80 }; 81 82 class MessagePumpForNonMainThreads final : public MessagePump { 83 public: 84 explicit MessagePumpForNonMainThreads(nsISerialEventTarget* aEventTarget) 85 : MessagePump(aEventTarget) {} 86 87 virtual void Run(base::MessagePump::Delegate* aDelegate) override; 88 89 private: 90 ~MessagePumpForNonMainThreads() = default; 91 }; 92 93 #if defined(XP_WIN) 94 // Extends the TYPE_UI message pump to process xpcom events. 95 class MessagePumpForNonMainUIThreads final : public base::MessagePumpForUI, 96 public nsIThreadObserver { 97 public: 98 NS_DECL_ISUPPORTS_INHERITED 99 NS_DECL_NSITHREADOBSERVER 100 101 public: 102 explicit MessagePumpForNonMainUIThreads(nsISerialEventTarget* aEventTarget) 103 : mInWait(false), mWaitLock("mInWait") {} 104 105 // The main run loop for this thread. 106 virtual void DoRunLoop() override; 107 108 virtual nsISerialEventTarget* GetXPCOMThread() override { 109 return nullptr; // not sure what to do with this one 110 } 111 112 protected: 113 void SetInWait() { 114 MutexAutoLock lock(mWaitLock); 115 mInWait = true; 116 } 117 118 void ClearInWait() { 119 MutexAutoLock lock(mWaitLock); 120 mInWait = false; 121 } 122 123 bool GetInWait() { 124 MutexAutoLock lock(mWaitLock); 125 return mInWait; 126 } 127 128 private: 129 ~MessagePumpForNonMainUIThreads() {} 130 131 bool mInWait MOZ_GUARDED_BY(mWaitLock); 132 mozilla::Mutex mWaitLock; 133 }; 134 #elif defined(XP_DARWIN) 135 // Extends the CFRunLoopBase message pump to process xpcom events. Based on 136 // MessagePumpNSRunLoop. 137 class MessagePumpForNonMainUIThreads final 138 : public base::MessagePumpCFRunLoopBase, 139 public nsIThreadObserver { 140 public: 141 NS_DECL_ISUPPORTS_INHERITED 142 NS_DECL_NSITHREADOBSERVER 143 144 public: 145 explicit MessagePumpForNonMainUIThreads(nsISerialEventTarget* aEventTarget); 146 147 void DoRun(base::MessagePump::Delegate* aDelegate) override; 148 void Quit() override; 149 150 nsISerialEventTarget* GetXPCOMThread() override { return mEventTarget; } 151 152 private: 153 ~MessagePumpForNonMainUIThreads(); 154 155 nsISerialEventTarget* mEventTarget; 156 157 // A source that doesn't do anything but provide something signalable 158 // attached to the run loop. This source will be signalled when Quit 159 // is called, to cause the loop to wake up so that it can stop. 160 CFRunLoopSourceRef quit_source_; 161 162 // False after Quit is called. 163 bool keep_running_; 164 165 DISALLOW_COPY_AND_ASSIGN(MessagePumpForNonMainUIThreads); 166 }; 167 #endif // defined(XP_DARWIN) 168 169 #if defined(MOZ_WIDGET_ANDROID) 170 /*` 171 * The MessagePumpForAndroidUI exists to enable IPDL in the Android UI thread. 172 * The Android UI thread event loop is controlled by Android. This prevents 173 * running an existing MessagePump implementation in the Android UI thread. In 174 * order to enable IPDL on the Android UI thread it is necessary to have a 175 * non-looping MessagePump. This class enables forwarding of nsIRunnables from 176 * MessageLoop::PostTask_Helper to the registered nsIEventTarget with out the 177 * need to control the event loop. The only member function that should be 178 * invoked is GetXPCOMThread. All other member functions will invoke MOZ_CRASH 179 */ 180 class MessagePumpForAndroidUI : public base::MessagePump { 181 public: 182 explicit MessagePumpForAndroidUI(nsISerialEventTarget* aEventTarget) 183 : mEventTarget(aEventTarget) {} 184 185 virtual void Run(Delegate* delegate); 186 virtual void Quit(); 187 virtual void ScheduleWork(); 188 virtual void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time); 189 virtual nsISerialEventTarget* GetXPCOMThread() { return mEventTarget; } 190 191 private: 192 ~MessagePumpForAndroidUI() {} 193 MessagePumpForAndroidUI() {} 194 195 nsISerialEventTarget* mEventTarget; 196 }; 197 #endif // defined(MOZ_WIDGET_ANDROID) 198 199 } /* namespace ipc */ 200 } /* namespace mozilla */ 201 202 #endif /* __IPC_GLUE_MESSAGEPUMP_H__ */