/work/obj-fuzz/dist/include/nsThread.h
Line | Count | Source (jump to first uncovered line) |
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 nsThread_h__ |
8 | | #define nsThread_h__ |
9 | | |
10 | | #include "mozilla/Mutex.h" |
11 | | #include "nsIIdlePeriod.h" |
12 | | #include "nsIThreadInternal.h" |
13 | | #include "nsISupportsPriority.h" |
14 | | #include "nsThreadUtils.h" |
15 | | #include "nsString.h" |
16 | | #include "nsTObserverArray.h" |
17 | | #include "mozilla/Attributes.h" |
18 | | #include "mozilla/LinkedList.h" |
19 | | #include "mozilla/MemoryReporting.h" |
20 | | #include "mozilla/SynchronizedEventQueue.h" |
21 | | #include "mozilla/NotNull.h" |
22 | | #include "mozilla/TimeStamp.h" |
23 | | #include "nsAutoPtr.h" |
24 | | #include "mozilla/AlreadyAddRefed.h" |
25 | | #include "mozilla/UniquePtr.h" |
26 | | #include "mozilla/Array.h" |
27 | | #include "mozilla/dom/DocGroup.h" |
28 | | |
29 | | namespace mozilla { |
30 | | class CycleCollectedJSContext; |
31 | | class ThreadEventTarget; |
32 | | } |
33 | | |
34 | | using mozilla::NotNull; |
35 | | |
36 | | class nsThreadEnumerator; |
37 | | |
38 | | // A native thread |
39 | | class nsThread |
40 | | : public nsIThreadInternal |
41 | | , public nsISupportsPriority |
42 | | , private mozilla::LinkedListElement<nsThread> |
43 | | { |
44 | | friend mozilla::LinkedList<nsThread>; |
45 | | friend mozilla::LinkedListElement<nsThread>; |
46 | | public: |
47 | | NS_DECL_THREADSAFE_ISUPPORTS |
48 | | NS_DECL_NSIEVENTTARGET_FULL |
49 | | NS_DECL_NSITHREAD |
50 | | NS_DECL_NSITHREADINTERNAL |
51 | | NS_DECL_NSISUPPORTSPRIORITY |
52 | | |
53 | | enum MainThreadFlag |
54 | | { |
55 | | MAIN_THREAD, |
56 | | NOT_MAIN_THREAD |
57 | | }; |
58 | | |
59 | | nsThread(NotNull<mozilla::SynchronizedEventQueue*> aQueue, |
60 | | MainThreadFlag aMainThread, |
61 | | uint32_t aStackSize); |
62 | | |
63 | | // Initialize this as a wrapper for a new PRThread, and optionally give it a name. |
64 | | nsresult Init(const nsACString& aName = NS_LITERAL_CSTRING("")); |
65 | | |
66 | | // Initialize this as a wrapper for the current PRThread. |
67 | | nsresult InitCurrentThread(); |
68 | | |
69 | | private: |
70 | | // Initializes the mThreadId and stack base/size members, and adds the thread |
71 | | // to the ThreadList(). |
72 | | void InitCommon(); |
73 | | |
74 | | public: |
75 | | // The PRThread corresponding to this thread. |
76 | | PRThread* GetPRThread() |
77 | 46 | { |
78 | 46 | return mThread; |
79 | 46 | } |
80 | | |
81 | 0 | const void* StackBase() const { return mStackBase; } |
82 | 0 | size_t StackSize() const { return mStackSize; } |
83 | | |
84 | 0 | uint32_t ThreadId() const { return mThreadId; } |
85 | | |
86 | | // If this flag is true, then the nsThread was created using |
87 | | // nsIThreadManager::NewThread. |
88 | | bool ShutdownRequired() |
89 | | { |
90 | | return mShutdownRequired; |
91 | | } |
92 | | |
93 | | void |
94 | | SetScriptObserver(mozilla::CycleCollectedJSContext* aScriptObserver); |
95 | | |
96 | | uint32_t |
97 | | RecursionDepth() const; |
98 | | |
99 | | void ShutdownComplete(NotNull<struct nsThreadShutdownContext*> aContext); |
100 | | |
101 | | void WaitForAllAsynchronousShutdowns(); |
102 | | |
103 | | static const uint32_t kRunnableNameBufSize = 1000; |
104 | | static mozilla::Array<char, kRunnableNameBufSize> sMainThreadRunnableName; |
105 | | |
106 | | void EnableInputEventPrioritization() |
107 | | { |
108 | | EventQueue()->EnableInputEventPrioritization(); |
109 | | } |
110 | | |
111 | | void FlushInputEventPrioritization() |
112 | | { |
113 | | EventQueue()->FlushInputEventPrioritization(); |
114 | | } |
115 | | |
116 | | void SuspendInputEventPrioritization() |
117 | | { |
118 | | EventQueue()->SuspendInputEventPrioritization(); |
119 | | } |
120 | | |
121 | | void ResumeInputEventPrioritization() |
122 | | { |
123 | | EventQueue()->ResumeInputEventPrioritization(); |
124 | | } |
125 | | |
126 | | #ifndef RELEASE_OR_BETA |
127 | | mozilla::TimeStamp& NextIdleDeadlineRef() { return mNextIdleDeadline; } |
128 | | #endif |
129 | | |
130 | | mozilla::SynchronizedEventQueue* EventQueue() { return mEvents.get(); } |
131 | | |
132 | | bool ShuttingDown() |
133 | | { |
134 | | return mShutdownContext != nullptr; |
135 | | } |
136 | | |
137 | | virtual mozilla::PerformanceCounter* GetPerformanceCounter(nsIRunnable* aEvent); |
138 | | |
139 | | size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; |
140 | | |
141 | | // Returns the size of this object, its PRThread, and its shutdown contexts, |
142 | | // but excluding its event queues. |
143 | | size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; |
144 | | |
145 | | size_t SizeOfEventQueues(mozilla::MallocSizeOf aMallocSizeOf) const; |
146 | | |
147 | | static nsThreadEnumerator Enumerate(); |
148 | | |
149 | | private: |
150 | | void DoMainThreadSpecificProcessing(bool aReallyWait); |
151 | | |
152 | | protected: |
153 | | friend class nsThreadShutdownEvent; |
154 | | |
155 | | friend class nsThreadEnumerator; |
156 | | |
157 | | virtual ~nsThread(); |
158 | | |
159 | | static void ThreadFunc(void* aArg); |
160 | | |
161 | | // Helper |
162 | | already_AddRefed<nsIThreadObserver> GetObserver() |
163 | 0 | { |
164 | 0 | nsIThreadObserver* obs; |
165 | 0 | nsThread::GetObserver(&obs); |
166 | 0 | return already_AddRefed<nsIThreadObserver>(obs); |
167 | 0 | } |
168 | | |
169 | | struct nsThreadShutdownContext* ShutdownInternal(bool aSync); |
170 | | |
171 | | friend class nsThreadManager; |
172 | | |
173 | | static mozilla::OffTheBooksMutex& ThreadListMutex(); |
174 | | static mozilla::LinkedList<nsThread>& ThreadList(); |
175 | | static void ClearThreadList(); |
176 | | |
177 | | RefPtr<mozilla::SynchronizedEventQueue> mEvents; |
178 | | RefPtr<mozilla::ThreadEventTarget> mEventTarget; |
179 | | |
180 | | // The shutdown contexts for any other threads we've asked to shut down. |
181 | | nsTArray<nsAutoPtr<struct nsThreadShutdownContext>> mRequestedShutdownContexts; |
182 | | // The shutdown context for ourselves. |
183 | | struct nsThreadShutdownContext* mShutdownContext; |
184 | | |
185 | | mozilla::CycleCollectedJSContext* mScriptObserver; |
186 | | |
187 | | PRThread* mThread; |
188 | | void* mStackBase = nullptr; |
189 | | uint32_t mStackSize; |
190 | | uint32_t mThreadId; |
191 | | |
192 | | uint32_t mNestedEventLoopDepth; |
193 | | uint32_t mCurrentEventLoopDepth; |
194 | | |
195 | | mozilla::Atomic<bool> mShutdownRequired; |
196 | | |
197 | | int8_t mPriority; |
198 | | |
199 | | uint8_t mIsMainThread; |
200 | | |
201 | | bool IsMainThread() const |
202 | | { |
203 | | return MainThreadFlag(mIsMainThread) == MAIN_THREAD; |
204 | | } |
205 | | |
206 | | // Set to true if this thread creates a JSRuntime. |
207 | | bool mCanInvokeJS; |
208 | | |
209 | | bool mHasTLSEntry = false; |
210 | | |
211 | | // Used to track which event is being executed by ProcessNextEvent |
212 | | nsCOMPtr<nsIRunnable> mCurrentEvent; |
213 | | |
214 | | mozilla::TimeStamp mCurrentEventStart; |
215 | | mozilla::TimeStamp mNextIdleDeadline; |
216 | | |
217 | | RefPtr<mozilla::PerformanceCounter> mCurrentPerformanceCounter; |
218 | | }; |
219 | | |
220 | | class MOZ_STACK_CLASS nsThreadEnumerator final |
221 | | { |
222 | | public: |
223 | | nsThreadEnumerator() |
224 | | : mMal(nsThread::ThreadListMutex()) |
225 | | {} |
226 | | |
227 | 0 | auto begin() { return nsThread::ThreadList().begin(); } |
228 | 0 | auto end() { return nsThread::ThreadList().end(); } |
229 | | |
230 | | private: |
231 | | mozilla::OffTheBooksMutexAutoLock mMal; |
232 | | }; |
233 | | |
234 | | #if defined(XP_UNIX) && !defined(ANDROID) && !defined(DEBUG) && HAVE_UALARM \ |
235 | | && defined(_GNU_SOURCE) |
236 | | # define MOZ_CANARY |
237 | | |
238 | | extern int sCanaryOutputFD; |
239 | | #endif |
240 | | |
241 | | #endif // nsThread_h__ |