From 8f04d5ed4995d8550306bd22cba27dd655a07662 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 31 Jul 2013 12:04:47 -0400 Subject: [PATCH] Bug 900047 - remove nsIOThreadPool code; r=jduell --- netwerk/base/src/nsIOThreadPool.cpp | 281 ---------------------------- netwerk/base/src/nsIOThreadPool.h | 14 -- 2 files changed, 295 deletions(-) delete mode 100644 netwerk/base/src/nsIOThreadPool.cpp delete mode 100644 netwerk/base/src/nsIOThreadPool.h diff --git a/netwerk/base/src/nsIOThreadPool.cpp b/netwerk/base/src/nsIOThreadPool.cpp deleted file mode 100644 index 41b4870d5b57..000000000000 --- a/netwerk/base/src/nsIOThreadPool.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsIEventTarget.h" -#include "nsIServiceManager.h" -#include "nsIObserverService.h" -#include "nsIObserver.h" -#include "nsAutoLock.h" -#include "nsCOMPtr.h" -#include "prclist.h" -#include "prlog.h" - -#if defined(PR_LOGGING) -// -// NSPR_LOG_MODULES=nsIOThreadPool:5 -// -static PRLogModuleInfo *gIOThreadPoolLog = nullptr; -#endif -#define LOG(args) PR_LOG(gIOThreadPoolLog, PR_LOG_DEBUG, args) - -// this number specifies the maximum number of threads. -#define MAX_THREADS 4 - -// this number specifies how long to wait before killing an idle thread. it's -// important to pick a large enough value here to minimize thread churn. -#define IDLE_TIMEOUT PR_SecondsToInterval(60) - -#define PLEVENT_FROM_LINK(_link) \ - ((PLEvent*) ((char*) (_link) - offsetof(PLEvent, link))) - -//----------------------------------------------------------------------------- -// pool of joinable threads used for general purpose i/o tasks -// -// the main entry point to this class is nsIEventTarget. events posted to -// the thread pool are dispatched on one of the threads. a variable number -// of threads are maintained. the threads die off if they remain idle for -// more than THREAD_IDLE_TIMEOUT. the thread pool shuts down when it receives -// the "xpcom-shutdown-threads" event. -//----------------------------------------------------------------------------- - -class nsIOThreadPool : public nsIEventTarget - , public nsIObserver -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIEVENTTARGET - NS_DECL_NSIOBSERVER - - nsresult Init(); - void Shutdown(); - -private: - virtual ~nsIOThreadPool(); - - static void ThreadFunc(void *); - - // mLock protects all (exceptions during Init and Shutdown) - PRLock *mLock; - PRCondVar *mIdleThreadCV; // notified to wake up an idle thread - PRCondVar *mExitThreadCV; // notified when a thread exits - uint32_t mNumThreads; // number of active + idle threads - uint32_t mNumIdleThreads; // number of idle threads - PRCList mEventQ; // queue of PLEvent structs - bool mShutdown; // set to true if shutting down - nsThreadPoolNaming mNaming; // thread name numbering -}; - -NS_IMPL_ISUPPORTS2(nsIOThreadPool, nsIEventTarget, nsIObserver) - -nsresult -nsIOThreadPool::Init() -{ -#if defined(PR_LOGGING) - if (!gIOThreadPoolLog) - gIOThreadPoolLog = PR_NewLogModule("nsIOThreadPool"); -#endif - - mNumThreads = 0; - mNumIdleThreads = 0; - mShutdown = false; - - mLock = nsAutoLock::NewLock("nsIOThreadPool::mLock"); - if (!mLock) - return NS_ERROR_OUT_OF_MEMORY; - - mIdleThreadCV = PR_NewCondVar(mLock); - if (!mIdleThreadCV) - return NS_ERROR_OUT_OF_MEMORY; - - mExitThreadCV = PR_NewCondVar(mLock); - if (!mExitThreadCV) - return NS_ERROR_OUT_OF_MEMORY; - - PR_INIT_CLIST(&mEventQ); - - // We want to shutdown the i/o thread pool at xpcom-shutdown-threads time. - nsCOMPtr os = mozilla::services::GetObserverService(); - if (os) - os->AddObserver(this, "xpcom-shutdown-threads", false); - return NS_OK; -} - -nsIOThreadPool::~nsIOThreadPool() -{ - LOG(("Destroying nsIOThreadPool @%p\n", this)); - -#ifdef DEBUG - NS_ASSERTION(PR_CLIST_IS_EMPTY(&mEventQ), "leaking events"); - NS_ASSERTION(mNumThreads == 0, "leaking thread(s)"); -#endif - - if (mIdleThreadCV) - PR_DestroyCondVar(mIdleThreadCV); - if (mExitThreadCV) - PR_DestroyCondVar(mExitThreadCV); - if (mLock) - nsAutoLock::DestroyLock(mLock); -} - -void -nsIOThreadPool::Shutdown() -{ - LOG(("nsIOThreadPool::Shutdown\n")); - - // synchronize with background threads... - { - nsAutoLock lock(mLock); - mShutdown = true; - - PR_NotifyAllCondVar(mIdleThreadCV); - - while (mNumThreads != 0) - PR_WaitCondVar(mExitThreadCV, PR_INTERVAL_NO_TIMEOUT); - } -} - -NS_IMETHODIMP -nsIOThreadPool::PostEvent(PLEvent *event) -{ - LOG(("nsIOThreadPool::PostEvent [event=%p]\n", event)); - - nsAutoLock lock(mLock); - - // if we are shutting down, then prevent additional events from being - // added to the queue... - if (mShutdown) - return NS_ERROR_UNEXPECTED; - - nsresult rv = NS_OK; - - PR_APPEND_LINK(&event->link, &mEventQ); - - // now, look for an available idle thread... - if (mNumIdleThreads) - PR_NotifyCondVar(mIdleThreadCV); // wake up an idle thread - - // or, try to create a new thread unless we have reached our maximum... - else if (mNumThreads < MAX_THREADS) { - NS_ADDREF_THIS(); // the thread owns a reference to us - mNumThreads++; - PRThread *thread = PR_CreateThread(PR_USER_THREAD, - ThreadFunc, - this, - PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, - 0); - if (!thread) { - NS_RELEASE_THIS(); - mNumThreads--; - rv = NS_ERROR_OUT_OF_MEMORY; - } - } - // else, we expect one of the active threads to process the event queue. - - return rv; -} - -NS_IMETHODIMP -nsIOThreadPool::IsOnCurrentThread(bool *result) -{ - // no one should be calling this method. if this assertion gets hit, - // then we need to think carefully about what this method should be - // returning. - NS_NOTREACHED("nsIOThreadPool::IsOnCurrentThread"); - - // fudging this a bit since we actually cover several threads... - *result = false; - return NS_OK; -} - -NS_IMETHODIMP -nsIOThreadPool::Observe(nsISupports *, const char *topic, const PRUnichar *) -{ - NS_ASSERTION(strcmp(topic, "xpcom-shutdown-threads") == 0, "unexpected topic"); - Shutdown(); - return NS_OK; -} - -void -nsIOThreadPool::ThreadFunc(void *arg) -{ - nsIOThreadPool *pool = (nsIOThreadPool *) arg; - - pool->mNaming.SetThreadPoolName("IO Thread"); - - LOG(("entering ThreadFunc\n")); - - { - nsAutoLock lock(pool->mLock); - - for (;;) { - PRIntervalTime start = PR_IntervalNow(), timeout = IDLE_TIMEOUT; - // - // wait for one or more of the following to occur: - // (1) the event queue has an event to process - // (2) the shutdown flag has been set - // (3) the thread has been idle for too long - // - // PR_WaitCondVar will return when any of these conditions is true. - // - while (PR_CLIST_IS_EMPTY(&pool->mEventQ) && !pool->mShutdown) { - pool->mNumIdleThreads++; - PR_WaitCondVar(pool->mIdleThreadCV, timeout); - pool->mNumIdleThreads--; - - PRIntervalTime delta = PR_IntervalNow() - start; - if (delta >= timeout) - break; - timeout -= delta; - start += delta; - } - - // if the queue is still empty, then kill this thread (either we - // are shutting down or the thread exceeded the idle timeout)... - if (PR_CLIST_IS_EMPTY(&pool->mEventQ)) - break; - - // handle one event at a time: we don't want this one thread to hog - // all the events while other threads may be able to help out ;-) - do { - PLEvent *event = PLEVENT_FROM_LINK(PR_LIST_HEAD(&pool->mEventQ)); - PR_REMOVE_AND_INIT_LINK(&event->link); - - LOG(("event:%p\n", event)); - - // release lock! - lock.unlock(); - PL_HandleEvent(event); - lock.lock(); - } - while (!PR_CLIST_IS_EMPTY(&pool->mEventQ)); - } - - // thread is going away... - pool->mNumThreads--; - PR_NotifyCondVar(pool->mExitThreadCV); - } - - // release our reference to the pool - NS_RELEASE(pool); - - LOG(("leaving ThreadFunc\n")); -} - -//----------------------------------------------------------------------------- - -NS_METHOD -net_NewIOThreadPool(nsISupports *outer, REFNSIID iid, void **result) -{ - nsIOThreadPool *pool = new nsIOThreadPool(); - if (!pool) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(pool); - nsresult rv = pool->Init(); - if (NS_SUCCEEDED(rv)) - rv = pool->QueryInterface(iid, result); - NS_RELEASE(pool); - return rv; -} diff --git a/netwerk/base/src/nsIOThreadPool.h b/netwerk/base/src/nsIOThreadPool.h deleted file mode 100644 index b91c314ee758..000000000000 --- a/netwerk/base/src/nsIOThreadPool.h +++ /dev/null @@ -1,14 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef nsIOThreadPool_h__ -#define nsIOThreadPool_h__ - -/** - * XPCOM constructor for nsIOThreadPool - */ -NS_METHOD NS_HIDDEN -net_NewIOThreadPool(nsISupports *outer, REFNSIID iid, void **result); - -#endif // nsIOThreadPool_h__