Bug 463988 - Gloda: mozStorageConnection holds lock while calling outside its module leading to PR_ASSERT(lock->owner != me) on shutting down while indexing is active. v1 add flag that indicates async thread is shutting down, don't call nsIThread::Shutdown with a lock held. r=sdwilsh.

This commit is contained in:
Andrew Sutherland 2008-12-13 18:59:17 -08:00
parent fa4cd0f9e9
commit ede141e1ac
2 changed files with 23 additions and 6 deletions

View File

@ -77,6 +77,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(mozStorageConnection, mozIStorageConnection)
mozStorageConnection::mozStorageConnection(mozIStorageService* aService) :
mDBConn(nsnull)
, mAsyncExecutionMutex(nsAutoLock::NewLock("AsyncExecutionMutex"))
, mAsyncExecutionThreadShuttingDown(PR_FALSE)
, mTransactionMutex(nsAutoLock::NewLock("TransactionMutex"))
, mTransactionInProgress(PR_FALSE)
, mFunctionsMutex(nsAutoLock::NewLock("FunctionsMutex"))
@ -230,14 +231,18 @@ mozStorageConnection::Close()
leafName.get()));
#endif
// The shutdown call runs any pending events to completion, so we want to
// do this before closing the connection.
// Flag that we are shutting down the async thread, so that
// getAsyncExecutionTarget knows not to expose/create the async thread.
{
nsAutoLock mutex(mAsyncExecutionMutex);
if (mAsyncExecutionThread) {
mAsyncExecutionThread->Shutdown();
mAsyncExecutionThread = nsnull;
}
mAsyncExecutionThreadShuttingDown = PR_TRUE;
}
// Shutdown the async thread if it exists. (Because we just set the flag,
// we are the only code that is going to be touching this variable from here
// on out.)
if (mAsyncExecutionThread) {
mAsyncExecutionThread->Shutdown();
mAsyncExecutionThread = nsnull;
}
#ifdef DEBUG
@ -950,6 +955,11 @@ already_AddRefed<nsIEventTarget>
mozStorageConnection::getAsyncExecutionTarget()
{
nsAutoLock mutex(mAsyncExecutionMutex);
// If we are shutting down the asynchronous thread, don't hand out any more
// references to the thread.
if (mAsyncExecutionThreadShuttingDown)
return nsnull;
if (!mAsyncExecutionThread) {
nsresult rv = NS_NewThread(getter_AddRefs(mAsyncExecutionThread));

View File

@ -115,6 +115,13 @@ protected:
* field.
*/
nsCOMPtr<nsIThread> mAsyncExecutionThread;
/**
* Set to true by Close() prior to actually shutting down the thread. This
* lets getAsyncExecutionTarget() know not to hand out any more thread
* references (or to create the thread in the first place). This variable
* should be accessed while holding the mAsyncExecutionMutex.
*/
PRBool mAsyncExecutionThreadShuttingDown;
PRLock *mTransactionMutex;
PRBool mTransactionInProgress;