Bug 525356 - windows debug unit tests: test_connection_executeAsync.js and test_statement_executeAsync.js failing frequently (fatal assertion)

Release on the calling thread so when the connections destructor is called, it
is not on the background thread.
r=asuth
a=dbaron

--HG--
extra : rebase_source : c546987a611b92ca319f17faf4163a3f5bc257f5
This commit is contained in:
Shawn Wilsher 2009-11-20 12:35:45 -08:00
parent 36fcc4e93c
commit b567077e43
3 changed files with 27 additions and 11 deletions

View File

@ -289,6 +289,7 @@ private:
Connection::Connection(Service *aService)
: sharedAsyncExecutionMutex("Connection::sharedAsyncExecutionMutex")
, threadOpenedOn(do_GetCurrentThread())
, mDBConn(nsnull)
, mAsyncExecutionMutex("Connection::mAsyncExecutionMutex")
, mAsyncExecutionThreadShuttingDown(false)
@ -297,7 +298,6 @@ Connection::Connection(Service *aService)
, mFunctionsMutex(nsAutoLock::NewLock("FunctionsMutex"))
, mProgressHandlerMutex(nsAutoLock::NewLock("ProgressHandlerMutex"))
, mProgressHandler(nsnull)
, mOpenedThread(do_GetCurrentThread())
, mStorageService(aService)
{
mFunctions.Init();
@ -517,7 +517,7 @@ Connection::setClosedState()
{
// Ensure that we are on the correct thread to close the database.
PRBool onOpenedThread;
nsresult rv = mOpenedThread->IsOnCurrentThread(&onOpenedThread);
nsresult rv = threadOpenedOn->IsOnCurrentThread(&onOpenedThread);
NS_ENSURE_SUCCESS(rv, rv);
if (!onOpenedThread) {
NS_ERROR("Must close the database on the thread that you opened it with!");
@ -550,7 +550,7 @@ Connection::internalClose()
{ // Ensure that we are being called on the thread we were opened with.
PRBool onOpenedThread = PR_FALSE;
(void)mOpenedThread->IsOnCurrentThread(&onOpenedThread);
(void)threadOpenedOn->IsOnCurrentThread(&onOpenedThread);
NS_ASSERTION(onOpenedThread,
"Not called on the thread the database was opened on!");
}

View File

@ -100,6 +100,12 @@ public:
*/
Mutex sharedAsyncExecutionMutex;
/**
* References the thread this database was opened on. This MUST be thread it
* is closed on.
*/
const nsCOMPtr<nsIThread> threadOpenedOn;
/**
* Closes the SQLite database, and warns about any non-finalized statements.
*/
@ -180,12 +186,6 @@ private:
PRLock *mProgressHandlerMutex;
nsCOMPtr<mozIStorageProgressHandler> mProgressHandler;
/**
* References the thread this database was opened on. This MUST be thread it
* is closed on.
*/
nsCOMPtr<nsIThread> mOpenedThread;
// This is here for two reasons: 1) It's used to make sure that the
// connections do not outlive the service. 2) Our custom collating functions
// call its localeCompareStrings() method.

View File

@ -43,6 +43,7 @@
#include "nsError.h"
#include "nsMemory.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
#include "nsIClassInfoImpl.h"
#include "nsIProgrammingLanguage.h"
@ -77,18 +78,33 @@ namespace {
class AsyncStatementFinalizer : public nsRunnable
{
public:
AsyncStatementFinalizer(sqlite3_stmt *aStatement)
/**
* Constructor for the event.
*
* @param aStatement
* The sqlite3_stmt to finalize on the background thread.
* @param aConnection
* The Connection that aStatement was created on. We hold a reference
* to this to ensure that if we are the last reference to the
* Connection, that we release it on the proper thread. The release
* call is proxied to the appropriate thread.
*/
AsyncStatementFinalizer(sqlite3_stmt *aStatement,
Connection *aConnection)
: mStatement(aStatement)
, mConnection(aConnection)
{
}
NS_IMETHOD Run()
{
(void)::sqlite3_finalize(mStatement);
(void)::NS_ProxyRelease(mConnection->threadOpenedOn, mConnection);
return NS_OK;
}
private:
sqlite3_stmt *mStatement;
nsCOMPtr<Connection> mConnection;
};
} // anonymous namespace
@ -401,7 +417,7 @@ Statement::Finalize()
}
else {
nsCOMPtr<nsIRunnable> event =
new AsyncStatementFinalizer(mCachedAsyncStatement);
new AsyncStatementFinalizer(mCachedAsyncStatement, mDBConnection);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = target->Dispatch(event, NS_DISPATCH_NORMAL);