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