diff --git a/mozilla/base/public/nsIThread.h b/mozilla/base/public/nsIThread.h index a74ffebeb96..bef5bad6b0a 100644 --- a/mozilla/base/public/nsIThread.h +++ b/mozilla/base/public/nsIThread.h @@ -107,9 +107,7 @@ public: NS_IMETHOD DispatchRequest(nsIRunnable* runnable) = 0; - NS_IMETHOD Join() = 0; - - NS_IMETHOD Interrupt() = 0; + NS_IMETHOD Shutdown() = 0; }; extern NS_BASE nsresult diff --git a/mozilla/base/src/nsThread.cpp b/mozilla/base/src/nsThread.cpp index 0a5bb7e810e..57fbe50f52f 100644 --- a/mozilla/base/src/nsThread.cpp +++ b/mozilla/base/src/nsThread.cpp @@ -231,7 +231,7 @@ nsIThread::GetCurrent(nsIThread* *result) nsThreadPool::nsThreadPool(PRUint32 minThreads, PRUint32 maxThreads) : mThreads(nsnull), mRequests(nsnull), - mMinThreads(minThreads), mMaxThreads(maxThreads) + mMinThreads(minThreads), mMaxThreads(maxThreads), mShuttingDown(PR_FALSE) { NS_INIT_REFCNT(); } @@ -285,6 +285,7 @@ nsThreadPool::Init(PRUint32 stackSize, nsThreadPool::~nsThreadPool() { + Shutdown(); if (mThreads) { // clean up the worker threads PRUint32 count = mThreads->Count(); @@ -311,10 +312,14 @@ nsThreadPool::DispatchRequest(nsIRunnable* runnable) nsresult rv; PR_EnterMonitor(mRequestMonitor); - rv = mRequests->AppendElement(runnable); - if (NS_SUCCEEDED(rv)) - PR_Notify(mRequestMonitor); - + if (mShuttingDown) { + rv = NS_ERROR_FAILURE; + } + else { + rv = mRequests->AppendElement(runnable); + if (NS_SUCCEEDED(rv)) + PR_Notify(mRequestMonitor); + } PR_ExitMonitor(mRequestMonitor); return rv; } @@ -330,11 +335,15 @@ nsThreadPool::GetRequest() PR_EnterMonitor(mRequestMonitor); while (mRequests->Count() == 0) { + if (mShuttingDown) { + rv = NS_ERROR_FAILURE; + break; + } // printf("thread %x waiting\n", PR_CurrentThread()); PRStatus status = PR_Wait(mRequestMonitor, PR_INTERVAL_NO_TIMEOUT); - if (status != PR_SUCCESS) { + if (status != PR_SUCCESS || mShuttingDown) { rv = NS_ERROR_FAILURE; - break; // interrupted -- quit + break; } } @@ -351,7 +360,7 @@ nsThreadPool::GetRequest() } NS_IMETHODIMP -nsThreadPool::Join() +nsThreadPool::Shutdown() { nsresult rv = NS_OK; PRUint32 count; @@ -368,29 +377,21 @@ nsThreadPool::Join() } PR_CExitMonitor(this); if (NS_FAILED(rv)) return rv; + + mShuttingDown = PR_TRUE; // then interrupt the threads and join them - Interrupt(); count = mThreads->Count(); for (i = 0; i < count; i++) { - nsIThread* thread = (nsIThread*)((*mThreads)[i]); - rv = thread->Join(); - if (NS_FAILED(rv)) return rv; - } - - return rv; -} - -NS_IMETHODIMP -nsThreadPool::Interrupt() -{ - nsresult rv = NS_OK; - PRUint32 count = mThreads->Count(); - for (PRUint32 i = 0; i < count; i++) { - nsIThread* thread = (nsIThread*)((*mThreads)[i]); + nsIThread* thread = (nsIThread*)((*mThreads)[0]); rv = thread->Interrupt(); if (NS_FAILED(rv)) return rv; + rv = thread->Join(); + if (NS_FAILED(rv)) return rv; + rv = mThreads->RemoveElementAt(0); + if (NS_FAILED(rv)) return rv; } + return rv; } @@ -456,6 +457,7 @@ nsThreadPoolRunnable::Run() PR_CNotify(mPool); PR_CExitMonitor(mPool); } +// printf("quitting %x, thread %x\n", this, PR_CurrentThread()); return rv; } diff --git a/mozilla/base/src/nsThread.h b/mozilla/base/src/nsThread.h index 51029eb6417..4f296aaa7cd 100644 --- a/mozilla/base/src/nsThread.h +++ b/mozilla/base/src/nsThread.h @@ -69,8 +69,7 @@ public: // nsIThreadPool methods: NS_IMETHOD DispatchRequest(nsIRunnable* runnable); - NS_IMETHOD Join(); - NS_IMETHOD Interrupt(); + NS_IMETHOD Shutdown(); // nsThreadPool methods: nsThreadPool(PRUint32 minThreads, PRUint32 maxThreads); @@ -89,6 +88,7 @@ protected: PRMonitor* mRequestMonitor; PRUint32 mMinThreads; PRUint32 mMaxThreads; + PRBool mShuttingDown; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/xpcom/threads/nsIThread.h b/mozilla/xpcom/threads/nsIThread.h index a74ffebeb96..bef5bad6b0a 100644 --- a/mozilla/xpcom/threads/nsIThread.h +++ b/mozilla/xpcom/threads/nsIThread.h @@ -107,9 +107,7 @@ public: NS_IMETHOD DispatchRequest(nsIRunnable* runnable) = 0; - NS_IMETHOD Join() = 0; - - NS_IMETHOD Interrupt() = 0; + NS_IMETHOD Shutdown() = 0; }; extern NS_BASE nsresult diff --git a/mozilla/xpcom/threads/nsThread.cpp b/mozilla/xpcom/threads/nsThread.cpp index 0a5bb7e810e..57fbe50f52f 100644 --- a/mozilla/xpcom/threads/nsThread.cpp +++ b/mozilla/xpcom/threads/nsThread.cpp @@ -231,7 +231,7 @@ nsIThread::GetCurrent(nsIThread* *result) nsThreadPool::nsThreadPool(PRUint32 minThreads, PRUint32 maxThreads) : mThreads(nsnull), mRequests(nsnull), - mMinThreads(minThreads), mMaxThreads(maxThreads) + mMinThreads(minThreads), mMaxThreads(maxThreads), mShuttingDown(PR_FALSE) { NS_INIT_REFCNT(); } @@ -285,6 +285,7 @@ nsThreadPool::Init(PRUint32 stackSize, nsThreadPool::~nsThreadPool() { + Shutdown(); if (mThreads) { // clean up the worker threads PRUint32 count = mThreads->Count(); @@ -311,10 +312,14 @@ nsThreadPool::DispatchRequest(nsIRunnable* runnable) nsresult rv; PR_EnterMonitor(mRequestMonitor); - rv = mRequests->AppendElement(runnable); - if (NS_SUCCEEDED(rv)) - PR_Notify(mRequestMonitor); - + if (mShuttingDown) { + rv = NS_ERROR_FAILURE; + } + else { + rv = mRequests->AppendElement(runnable); + if (NS_SUCCEEDED(rv)) + PR_Notify(mRequestMonitor); + } PR_ExitMonitor(mRequestMonitor); return rv; } @@ -330,11 +335,15 @@ nsThreadPool::GetRequest() PR_EnterMonitor(mRequestMonitor); while (mRequests->Count() == 0) { + if (mShuttingDown) { + rv = NS_ERROR_FAILURE; + break; + } // printf("thread %x waiting\n", PR_CurrentThread()); PRStatus status = PR_Wait(mRequestMonitor, PR_INTERVAL_NO_TIMEOUT); - if (status != PR_SUCCESS) { + if (status != PR_SUCCESS || mShuttingDown) { rv = NS_ERROR_FAILURE; - break; // interrupted -- quit + break; } } @@ -351,7 +360,7 @@ nsThreadPool::GetRequest() } NS_IMETHODIMP -nsThreadPool::Join() +nsThreadPool::Shutdown() { nsresult rv = NS_OK; PRUint32 count; @@ -368,29 +377,21 @@ nsThreadPool::Join() } PR_CExitMonitor(this); if (NS_FAILED(rv)) return rv; + + mShuttingDown = PR_TRUE; // then interrupt the threads and join them - Interrupt(); count = mThreads->Count(); for (i = 0; i < count; i++) { - nsIThread* thread = (nsIThread*)((*mThreads)[i]); - rv = thread->Join(); - if (NS_FAILED(rv)) return rv; - } - - return rv; -} - -NS_IMETHODIMP -nsThreadPool::Interrupt() -{ - nsresult rv = NS_OK; - PRUint32 count = mThreads->Count(); - for (PRUint32 i = 0; i < count; i++) { - nsIThread* thread = (nsIThread*)((*mThreads)[i]); + nsIThread* thread = (nsIThread*)((*mThreads)[0]); rv = thread->Interrupt(); if (NS_FAILED(rv)) return rv; + rv = thread->Join(); + if (NS_FAILED(rv)) return rv; + rv = mThreads->RemoveElementAt(0); + if (NS_FAILED(rv)) return rv; } + return rv; } @@ -456,6 +457,7 @@ nsThreadPoolRunnable::Run() PR_CNotify(mPool); PR_CExitMonitor(mPool); } +// printf("quitting %x, thread %x\n", this, PR_CurrentThread()); return rv; } diff --git a/mozilla/xpcom/threads/nsThread.h b/mozilla/xpcom/threads/nsThread.h index 51029eb6417..4f296aaa7cd 100644 --- a/mozilla/xpcom/threads/nsThread.h +++ b/mozilla/xpcom/threads/nsThread.h @@ -69,8 +69,7 @@ public: // nsIThreadPool methods: NS_IMETHOD DispatchRequest(nsIRunnable* runnable); - NS_IMETHOD Join(); - NS_IMETHOD Interrupt(); + NS_IMETHOD Shutdown(); // nsThreadPool methods: nsThreadPool(PRUint32 minThreads, PRUint32 maxThreads); @@ -89,6 +88,7 @@ protected: PRMonitor* mRequestMonitor; PRUint32 mMinThreads; PRUint32 mMaxThreads; + PRBool mShuttingDown; }; ////////////////////////////////////////////////////////////////////////////////