mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
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:
parent
fa4cd0f9e9
commit
ede141e1ac
@ -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));
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user