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 #endif 14 15 #include "base/time.h" 16 #include "mozilla/Attributes.h" 17 #include "mozilla/Mutex.h" 18 #include "nsCOMPtr.h" 19 #include "nsIThreadInternal.h" 20 21 class nsIEventTarget; 22 class nsITimer; 23 24 namespace mozilla { 25 namespace ipc { 26 27 class DoWorkRunnable; 28 29 class MessagePump : public base::MessagePumpDefault { 30 friend class DoWorkRunnable; 31 32 public: 33 explicit MessagePump(nsIEventTarget* aEventTarget); 34 35 // From base::MessagePump. 36 virtual void Run(base::MessagePump::Delegate* aDelegate) override; 37 38 // From base::MessagePump. 39 virtual void ScheduleWork() override; 40 41 // From base::MessagePump. 42 virtual void ScheduleWorkForNestedLoop() override; 43 44 // From base::MessagePump. 45 virtual void ScheduleDelayedWork( 46 const base::TimeTicks& aDelayedWorkTime) override; 47 48 virtual nsIEventTarget* GetXPCOMThread() override; 49 50 protected: 51 virtual ~MessagePump(); 52 53 private: 54 // Only called by DoWorkRunnable. 55 void DoDelayedWork(base::MessagePump::Delegate* aDelegate); 56 57 protected: 58 nsIEventTarget* mEventTarget; 59 60 // mDelayedWorkTimer and mEventTarget are set in Run() by this class or its 61 // subclasses. 62 nsCOMPtr<nsITimer> mDelayedWorkTimer; 63 64 private: 65 // Only accessed by this class. 66 RefPtr<DoWorkRunnable> mDoWorkEvent; 67 }; 68 69 class MessagePumpForChildProcess final : public MessagePump { 70 public: MessagePumpForChildProcess()71 MessagePumpForChildProcess() : MessagePump(nullptr), mFirstRun(true) {} 72 73 virtual void Run(base::MessagePump::Delegate* aDelegate) override; 74 75 private: ~MessagePumpForChildProcess()76 ~MessagePumpForChildProcess() {} 77 78 bool mFirstRun; 79 }; 80 81 class MessagePumpForNonMainThreads final : public MessagePump { 82 public: MessagePumpForNonMainThreads(nsIEventTarget * aEventTarget)83 explicit MessagePumpForNonMainThreads(nsIEventTarget* aEventTarget) 84 : MessagePump(aEventTarget) {} 85 86 virtual void Run(base::MessagePump::Delegate* aDelegate) override; 87 88 private: ~MessagePumpForNonMainThreads()89 ~MessagePumpForNonMainThreads() {} 90 }; 91 92 #if defined(XP_WIN) 93 // Extends the TYPE_UI message pump to process xpcom events. Currently only 94 // implemented for Win. 95 class MessagePumpForNonMainUIThreads final : public base::MessagePumpForUI, 96 public nsIThreadObserver { 97 public: 98 // We don't want xpcom refing, chromium controls our lifetime via 99 // RefCountedThreadSafe. NS_IMETHOD_(MozExternalRefCountType)100 NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override { return 2; } Release(void)101 NS_IMETHOD_(MozExternalRefCountType) Release(void) override { return 1; } 102 NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override; 103 104 NS_DECL_NSITHREADOBSERVER 105 106 public: MessagePumpForNonMainUIThreads(nsIEventTarget * aEventTarget)107 explicit MessagePumpForNonMainUIThreads(nsIEventTarget* aEventTarget) 108 : mInWait(false), mWaitLock("mInWait") {} 109 110 // The main run loop for this thread. 111 virtual void DoRunLoop() override; 112 GetXPCOMThread()113 virtual nsIEventTarget* GetXPCOMThread() override { 114 return nullptr; // not sure what to do with this one 115 } 116 117 protected: SetInWait()118 void SetInWait() { 119 MutexAutoLock lock(mWaitLock); 120 mInWait = true; 121 } 122 ClearInWait()123 void ClearInWait() { 124 MutexAutoLock lock(mWaitLock); 125 mInWait = false; 126 } 127 GetInWait()128 bool GetInWait() { 129 MutexAutoLock lock(mWaitLock); 130 return mInWait; 131 } 132 133 private: ~MessagePumpForNonMainUIThreads()134 ~MessagePumpForNonMainUIThreads() {} 135 136 bool mInWait; 137 mozilla::Mutex mWaitLock; 138 }; 139 #endif // defined(XP_WIN) 140 141 #if defined(MOZ_WIDGET_ANDROID) 142 /*` 143 * The MessagePumpForAndroidUI exists to enable IPDL in the Android UI thread. 144 * The Android UI thread event loop is controlled by Android. This prevents 145 * running an existing MessagePump implementation in the Android UI thread. In 146 * order to enable IPDL on the Android UI thread it is necessary to have a 147 * non-looping MessagePump. This class enables forwarding of nsIRunnables from 148 * MessageLoop::PostTask_Helper to the registered nsIEventTarget with out the 149 * need to control the event loop. The only member function that should be 150 * invoked is GetXPCOMThread. All other member functions will invoke MOZ_CRASH 151 */ 152 class MessagePumpForAndroidUI : public base::MessagePump { 153 public: MessagePumpForAndroidUI(nsIEventTarget * aEventTarget)154 MessagePumpForAndroidUI(nsIEventTarget* aEventTarget) 155 : mEventTarget(aEventTarget) {} 156 157 virtual void Run(Delegate* delegate); 158 virtual void Quit(); 159 virtual void ScheduleWork(); 160 virtual void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time); GetXPCOMThread()161 virtual nsIEventTarget* GetXPCOMThread() { return mEventTarget; } 162 163 private: ~MessagePumpForAndroidUI()164 ~MessagePumpForAndroidUI() {} MessagePumpForAndroidUI()165 MessagePumpForAndroidUI() {} 166 167 nsIEventTarget* mEventTarget; 168 }; 169 #endif // defined(MOZ_WIDGET_ANDROID) 170 171 } /* namespace ipc */ 172 } /* namespace mozilla */ 173 174 #endif /* __IPC_GLUE_MESSAGEPUMP_H__ */ 175