Coverage Report

Created: 2018-09-25 14:53

/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__