Backed out changesets d8fd745a0095 and 30b7ebdf5c99 (bug 924480) for robocop-3 failures.
[gecko.git] / xpcom / threads / nsThread.h
blob0181c5acadeac57e2816c00ff40e1d473a77383f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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/. */
7 #ifndef nsThread_h__
8 #define nsThread_h__
10 #include "mozilla/Mutex.h"
11 #include "nsIThreadInternal.h"
12 #include "nsISupportsPriority.h"
13 #include "nsEventQueue.h"
14 #include "nsThreadUtils.h"
15 #include "nsString.h"
16 #include "nsTObserverArray.h"
17 #include "mozilla/Attributes.h"
19 // A native thread
20 class nsThread MOZ_FINAL : public nsIThreadInternal,
21 public nsISupportsPriority
23 public:
24 NS_DECL_THREADSAFE_ISUPPORTS
25 NS_DECL_NSIEVENTTARGET
26 NS_DECL_NSITHREAD
27 NS_DECL_NSITHREADINTERNAL
28 NS_DECL_NSISUPPORTSPRIORITY
30 enum MainThreadFlag {
31 MAIN_THREAD,
32 NOT_MAIN_THREAD
35 nsThread(MainThreadFlag aMainThread, uint32_t aStackSize);
37 // Initialize this as a wrapper for a new PRThread.
38 nsresult Init();
40 // Initialize this as a wrapper for the current PRThread.
41 nsresult InitCurrentThread();
43 // The PRThread corresponding to this thread.
44 PRThread *GetPRThread() { return mThread; }
46 // If this flag is true, then the nsThread was created using
47 // nsIThreadManager::NewThread.
48 bool ShutdownRequired() { return mShutdownRequired; }
50 // Clear the observer list.
51 void ClearObservers() { mEventObservers.Clear(); }
53 static nsresult
54 SetMainThreadObserver(nsIThreadObserver* aObserver);
56 private:
57 static nsIThreadObserver* sMainThreadObserver;
59 friend class nsThreadShutdownEvent;
61 ~nsThread();
63 bool ShuttingDown() { return mShutdownContext != nullptr; }
65 static void ThreadFunc(void *arg);
67 // Helper
68 already_AddRefed<nsIThreadObserver> GetObserver() {
69 nsIThreadObserver *obs;
70 nsThread::GetObserver(&obs);
71 return already_AddRefed<nsIThreadObserver>(obs);
74 // Wrappers for event queue methods:
75 bool GetEvent(bool mayWait, nsIRunnable **event) {
76 return mEvents.GetEvent(mayWait, event);
78 nsresult PutEvent(nsIRunnable *event);
80 // This lock protects access to mObserver, mEvents and mEventsAreDoomed.
81 // All of those fields are only modified on the thread itself (never from
82 // another thread). This means that we can avoid holding the lock while
83 // using mObserver and mEvents on the thread itself. When calling PutEvent
84 // on mEvents, we have to hold the lock to synchronize with PopEventQueue.
85 mozilla::Mutex mLock;
87 nsCOMPtr<nsIThreadObserver> mObserver;
89 // Only accessed on the target thread.
90 nsAutoTObserverArray<nsCOMPtr<nsIThreadObserver>, 2> mEventObservers;
92 nsEventQueue mEvents;
94 int32_t mPriority;
95 PRThread *mThread;
96 uint32_t mRunningEvent; // counter
97 uint32_t mStackSize;
99 struct nsThreadShutdownContext *mShutdownContext;
101 bool mShutdownRequired;
102 // Set to true when events posted to this thread will never run.
103 bool mEventsAreDoomed;
104 MainThreadFlag mIsMainThread;
107 //-----------------------------------------------------------------------------
109 class nsThreadSyncDispatch : public nsRunnable {
110 public:
111 nsThreadSyncDispatch(nsIThread *origin, nsIRunnable *task)
112 : mOrigin(origin), mSyncTask(task), mResult(NS_ERROR_NOT_INITIALIZED) {
115 bool IsPending() {
116 return mSyncTask != nullptr;
119 nsresult Result() {
120 return mResult;
123 private:
124 NS_DECL_NSIRUNNABLE
126 nsCOMPtr<nsIThread> mOrigin;
127 nsCOMPtr<nsIRunnable> mSyncTask;
128 nsresult mResult;
131 #endif // nsThread_h__