mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-12 18:50:08 +00:00
Fixed thread pool shutdown.
This commit is contained in:
parent
020ff3537f
commit
bf4df879ef
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user