diff --git a/netwerk/base/nsStreamTransportService.cpp b/netwerk/base/nsStreamTransportService.cpp index 2b2088a84878..b01fd52a8cf1 100644 --- a/netwerk/base/nsStreamTransportService.cpp +++ b/netwerk/base/nsStreamTransportService.cpp @@ -182,7 +182,8 @@ nsresult nsStreamTransportService::Init() { // Configure the pool mPool->SetName(NS_LITERAL_CSTRING("StreamTrans")); mPool->SetThreadLimit(25); - mPool->SetIdleThreadLimit(1); + mPool->SetIdleThreadLimit(5); + mPool->SetIdleThreadTimeoutRegressive(true); mPool->SetIdleThreadTimeout(PR_SecondsToInterval(30)); nsCOMPtr obsSvc = mozilla::services::GetObserverService(); diff --git a/xpcom/threads/nsIThreadPool.idl b/xpcom/threads/nsIThreadPool.idl index 98f3a6efa288..f45ab6c892eb 100644 --- a/xpcom/threads/nsIThreadPool.idl +++ b/xpcom/threads/nsIThreadPool.idl @@ -68,6 +68,14 @@ interface nsIThreadPool : nsIEventTarget */ attribute unsigned long idleThreadTimeout; + /** + * If set to true the idle timeout will be calculated as idleThreadTimeout + * divideded by the number of idle threads at the moment. This may help + * save memory allocations but still keep reasonable amount of idle threads. + * Default is false, use |idleThreadTimeout| for all threads. + */ + attribute boolean idleThreadTimeoutRegressive; + /** * Get/set the number of bytes reserved for the stack of all threads in * the pool. By default this is nsIThreadManager::DEFAULT_STACK_SIZE. diff --git a/xpcom/threads/nsThreadPool.cpp b/xpcom/threads/nsThreadPool.cpp index 621975dbb236..7a87cac9390c 100644 --- a/xpcom/threads/nsThreadPool.cpp +++ b/xpcom/threads/nsThreadPool.cpp @@ -51,7 +51,8 @@ nsThreadPool::nsThreadPool() mIdleThreadTimeout(DEFAULT_IDLE_THREAD_TIMEOUT), mIdleCount(0), mStackSize(nsIThreadManager::DEFAULT_STACK_SIZE), - mShutdown(false) { + mShutdown(false), + mRegressiveMaxIdleTime(false) { LOG(("THRD-P(%p) constructor!!!\n", this)); } @@ -182,8 +183,10 @@ nsThreadPool::Run() { event = mEvents.GetEvent(nullptr, lock); if (!event) { TimeStamp now = TimeStamp::Now(); - TimeDuration timeout = - TimeDuration::FromMilliseconds(mIdleThreadTimeout); + uint32_t idleTimeoutDivider = + (mIdleCount && mRegressiveMaxIdleTime) ? mIdleCount : 1; + TimeDuration timeout = TimeDuration::FromMilliseconds( + static_cast(mIdleThreadTimeout) / idleTimeoutDivider); // If we are shutting down, then don't keep any idle threads if (mShutdown) { @@ -511,6 +514,26 @@ nsThreadPool::SetIdleThreadTimeout(uint32_t aValue) { return NS_OK; } +NS_IMETHODIMP +nsThreadPool::GetIdleThreadTimeoutRegressive(bool* aValue) { + *aValue = mRegressiveMaxIdleTime; + return NS_OK; +} + +NS_IMETHODIMP +nsThreadPool::SetIdleThreadTimeoutRegressive(bool aValue) { + MutexAutoLock lock(mMutex); + bool oldRegressive = mRegressiveMaxIdleTime; + mRegressiveMaxIdleTime = aValue; + + // Would setting regressive timeout effect idle threads? + if (mRegressiveMaxIdleTime > oldRegressive && mIdleCount > 1) { + mEventsAvailable + .NotifyAll(); // wake up threads so they observe this change + } + return NS_OK; +} + NS_IMETHODIMP nsThreadPool::GetThreadStackSize(uint32_t* aValue) { MutexAutoLock lock(mMutex); diff --git a/xpcom/threads/nsThreadPool.h b/xpcom/threads/nsThreadPool.h index 1795717d77ce..0370ff567c00 100644 --- a/xpcom/threads/nsThreadPool.h +++ b/xpcom/threads/nsThreadPool.h @@ -46,6 +46,7 @@ class nsThreadPool final : public nsIThreadPool, public nsIRunnable { uint32_t mStackSize; nsCOMPtr mListener; bool mShutdown; + bool mRegressiveMaxIdleTime; nsCString mName; nsThreadPoolNaming mThreadNaming; };