commit 6ced9e58b4ecfd128e421d207e8fa85715de5a9e
parent b0cc2184b03315b546d1621072341ac2c23a6f36
Author: Jens Stutte <jstutte@mozilla.com>
Date: Wed, 3 Dec 2025 08:03:56 +0000
Bug 2003538 - Correct mIsAPoolThreadFree calculation to include idle threads. r=xpcom-reviewers,nika
Differential Revision: https://phabricator.services.mozilla.com/D274761
Diffstat:
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp
@@ -553,7 +553,7 @@ nsThread::nsThread(NotNull<SynchronizedEventQueue*> aQueue,
mIsMainThread(aMainThread == MAIN_THREAD),
mUseHangMonitor(aMainThread == MAIN_THREAD),
mIsUiThread(aOptions.isUiThread),
- mIsAPoolThreadFree(nullptr),
+ mIsAPoolThreadFreePtr(nullptr),
mCanInvokeJS(false),
mPerformanceCounterState(mNestedEventLoopDepth, mIsMainThread,
aOptions.longTaskLength) {
@@ -721,9 +721,9 @@ nsThread::UnregisterShutdownTask(nsITargetShutdownTask* aTask) {
NS_IMETHODIMP
nsThread::GetRunningEventDelay(TimeDuration* aDelay, TimeStamp* aStart) {
- if (mIsAPoolThreadFree && *mIsAPoolThreadFree) {
- // if there are unstarted threads in the pool, a new event to the
- // pool would not be delayed at all (beyond thread start time)
+ if (mIsAPoolThreadFreePtr && *mIsAPoolThreadFreePtr) {
+ // If there are idle or unstarted threads in the pool, a new event to the
+ // pool would not be delayed at all (beyond thread wake / start time).
*aDelay = TimeDuration();
*aStart = TimeStamp();
} else {
diff --git a/xpcom/threads/nsThread.h b/xpcom/threads/nsThread.h
@@ -202,9 +202,9 @@ class nsThread : public nsIThreadInternal,
bool ShutdownRequired() { return mShutdownRequired; }
// Lets GetRunningEventDelay() determine if the pool this is part
- // of has an unstarted thread
+ // of has an idle or unstarted thread.
void SetPoolThreadFreePtr(mozilla::Atomic<bool, mozilla::Relaxed>* aPtr) {
- mIsAPoolThreadFree = aPtr;
+ mIsAPoolThreadFreePtr = aPtr;
}
void SetScriptObserver(mozilla::CycleCollectedJSContext* aScriptObserver);
@@ -292,7 +292,7 @@ class nsThread : public nsIThreadInternal,
const bool mIsMainThread;
bool mUseHangMonitor;
const bool mIsUiThread;
- mozilla::Atomic<bool, mozilla::Relaxed>* mIsAPoolThreadFree;
+ mozilla::Atomic<bool, mozilla::Relaxed>* mIsAPoolThreadFreePtr;
// Set to true if this thread creates a JSRuntime.
bool mCanInvokeJS;
diff --git a/xpcom/threads/nsThreadPool.cpp b/xpcom/threads/nsThreadPool.cpp
@@ -220,6 +220,7 @@ nsresult nsThreadPool::PutEvent(already_AddRefed<nsIRunnable> aEvent,
mThreads.AppendObject(thread);
if (mThreads.Count() >= (int32_t)mThreadLimit) {
+ MOZ_ASSERT(mMRUIdleThreads.isEmpty());
mIsAPoolThreadFree = false;
}
@@ -389,10 +390,11 @@ nsThreadPool::Run() {
DebugOnly<bool> found = mThreads.RemoveObject(current);
MOZ_ASSERT(found || (mShutdown && mThreads.IsEmpty()));
- // Keep track if there are threads available to start. If we are
- // shutting down, no new threads can start.
+ // Keep track if there are threads available. If we are shutting
+ // down, no new threads can start.
mIsAPoolThreadFree =
- !mShutdown && (mThreads.Count() < (int32_t)mThreadLimit);
+ !mMRUIdleThreads.isEmpty() ||
+ (!mShutdown && mThreads.Count() < (int32_t)mThreadLimit);
} else {
current->SetRunningEventDelay(TimeDuration(), TimeStamp());
@@ -560,7 +562,7 @@ nsThreadPool::ShutdownWithTimeout(int32_t aTimeoutMs) {
// join each thread.
name = mName;
mShutdown = true;
- mIsAPoolThreadFree = false;
+ mIsAPoolThreadFree = !mMRUIdleThreads.isEmpty();
NotifyChangeToAllIdleThreads();
// From now on we do not allow the creation of new threads, and threads