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/. */
7 #ifndef nsThreadManager_h__
8 #define nsThreadManager_h__
10 #include "nsIThreadManager.h"
12 #include "mozilla/ShutdownPhase.h"
18 class IdleTaskManager
;
19 class SynchronizedEventQueue
;
24 } // namespace mozilla
26 class BackgroundEventTarget
;
28 class nsThreadManager
: public nsIThreadManager
{
31 NS_DECL_NSITHREADMANAGER
33 static nsThreadManager
& get();
37 // Shutdown all threads other than the main thread. This function should only
38 // be called on the main thread of the application process.
39 void ShutdownNonMainThreads();
41 // Finish shutting down all threads. This function must be called after
42 // ShutdownNonMainThreads and will delete the BackgroundEventTarget and
43 // take the main thread event target out of commission, but without
44 // releasing the underlying nsThread object.
45 void ShutdownMainThread();
47 // Release the underlying main thread nsThread object.
48 void ReleaseMainThread();
50 // Called by nsThread to inform the ThreadManager it exists. This method
51 // must be called when the given thread is the current thread.
52 void RegisterCurrentThread(nsThread
& aThread
);
54 // Called by nsThread to inform the ThreadManager it is going away. This
55 // method must be called when the given thread is the current thread.
56 void UnregisterCurrentThread(nsThread
& aThread
);
58 // Returns the current thread. Returns null if OOM or if ThreadManager isn't
59 // initialized. Creates the nsThread if one does not exist yet.
60 nsThread
* GetCurrentThread();
62 // Returns true iff the currently running thread has an nsThread associated
63 // with it (ie; whether this is a thread that we can dispatch runnables to).
64 bool IsNSThread() const;
66 // CreateCurrentThread sets up an nsThread for the current thread. It uses the
67 // event queue and main thread flags passed in. It should only be called once
68 // for the current thread. After it returns, GetCurrentThread() will return
69 // the thread that was created. GetCurrentThread() will also create a thread
70 // (lazily), but it doesn't allow the queue or main-thread attributes to be
72 nsThread
* CreateCurrentThread(mozilla::SynchronizedEventQueue
* aQueue
);
74 nsresult
DispatchToBackgroundThread(nsIRunnable
* aEvent
,
75 uint32_t aDispatchFlags
);
77 already_AddRefed
<mozilla::TaskQueue
> CreateBackgroundTaskQueue(
82 void EnableMainThreadEventPrioritization();
83 void FlushInputEventPrioritization();
84 void SuspendInputEventPrioritization();
85 void ResumeInputEventPrioritization();
87 static bool MainThreadHasPendingHighPriorityEvents();
89 nsIThread
* GetMainThreadWeak() { return mMainThread
; }
91 // Low level methods for interacting with the global thread list. Be very
92 // careful when holding `ThreadListMutex()` as no new threads can be started
94 mozilla::OffTheBooksMutex
& ThreadListMutex() MOZ_RETURN_CAPABILITY(mMutex
) {
98 bool AllowNewXPCOMThreads() MOZ_EXCLUDES(mMutex
);
99 bool AllowNewXPCOMThreadsLocked() MOZ_REQUIRES(mMutex
) {
100 return mState
== State::eActive
;
103 mozilla::LinkedList
<nsThread
>& ThreadList() MOZ_REQUIRES(mMutex
) {
108 friend class mozilla::NeverDestroyed
<nsThreadManager
>;
112 nsresult
SpinEventLoopUntilInternal(
113 const nsACString
& aVeryGoodReasonToDoThis
,
114 nsINestedEventLoopCondition
* aCondition
,
115 mozilla::ShutdownPhase aShutdownPhaseToCheck
);
117 static void ReleaseThread(void* aData
);
119 enum class State
: uint8_t {
120 // The thread manager has yet to be initialized.
122 // The thread manager is active, and operating normally.
124 // The thread manager is in XPCOM shutdown. New calls to NS_NewNamedThread
125 // will fail, as all XPCOM threads are required to be shutting down.
129 unsigned mCurThreadIndex
; // thread-local-storage index
130 RefPtr
<nsThread
> mMainThread
;
132 mutable mozilla::OffTheBooksMutex mMutex
;
134 // Current state in the thread manager's lifecycle. See docs above.
135 State mState
MOZ_GUARDED_BY(mMutex
);
137 // Global list of active nsThread instances, including both explicitly and
138 // implicitly created threads.
140 // NOTE: New entries to this list _may_ be added after mAllowNewThreads has
141 // been cleared, but only for implicitly created thread wrappers which are
142 // not shut down during XPCOM shutdown.
143 mozilla::LinkedList
<nsThread
> mThreadList
MOZ_GUARDED_BY(mMutex
);
145 // Shared event target used for background runnables.
146 RefPtr
<BackgroundEventTarget
> mBackgroundEventTarget
MOZ_GUARDED_BY(mMutex
);
149 #define NS_THREADMANAGER_CID \
150 { /* 7a4204c6-e45a-4c37-8ebb-6709a22c917c */ \
151 0x7a4204c6, 0xe45a, 0x4c37, { \
152 0x8e, 0xbb, 0x67, 0x09, 0xa2, 0x2c, 0x91, 0x7c \
156 #endif // nsThreadManager_h__