зеркало из https://github.com/mozilla/gecko-dev.git
Backout of bug 494828 and bug 505550 due to orange.
This commit is contained in:
Родитель
0f6c391b1a
Коммит
5cefb953b9
|
@ -83,7 +83,6 @@ EXPORTS
|
|||
sqlite3_create_module
|
||||
sqlite3_data_count
|
||||
sqlite3_db_handle
|
||||
sqlite3_db_mutex
|
||||
sqlite3_declare_vtab
|
||||
sqlite3_enable_load_extension
|
||||
sqlite3_enable_shared_cache
|
||||
|
|
|
@ -249,8 +249,10 @@ Connection::Connection(Service *aService)
|
|||
, mDBConn(nsnull)
|
||||
, mAsyncExecutionMutex(nsAutoLock::NewLock("AsyncExecutionMutex"))
|
||||
, mAsyncExecutionThreadShuttingDown(PR_FALSE)
|
||||
, mDBMutex("Connection::mDBMutex")
|
||||
, mTransactionMutex(nsAutoLock::NewLock("TransactionMutex"))
|
||||
, mTransactionInProgress(PR_FALSE)
|
||||
, mFunctionsMutex(nsAutoLock::NewLock("FunctionsMutex"))
|
||||
, mProgressHandlerMutex(nsAutoLock::NewLock("ProgressHandlerMutex"))
|
||||
, mProgressHandler(nsnull)
|
||||
, mStorageService(aService)
|
||||
{
|
||||
|
@ -261,6 +263,9 @@ Connection::~Connection()
|
|||
{
|
||||
(void)Close();
|
||||
nsAutoLock::DestroyLock(mAsyncExecutionMutex);
|
||||
nsAutoLock::DestroyLock(mTransactionMutex);
|
||||
nsAutoLock::DestroyLock(mFunctionsMutex);
|
||||
nsAutoLock::DestroyLock(mProgressHandlerMutex);
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(
|
||||
|
@ -296,6 +301,9 @@ Connection::initialize(nsIFile *aDatabaseFile)
|
|||
{
|
||||
NS_ASSERTION (!mDBConn, "Initialize called on already opened database!");
|
||||
NS_ENSURE_TRUE(mAsyncExecutionMutex, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_TRUE(mTransactionMutex, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_TRUE(mFunctionsMutex, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_TRUE(mProgressHandlerMutex, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
int srv;
|
||||
nsresult rv;
|
||||
|
@ -318,9 +326,6 @@ Connection::initialize(nsIFile *aDatabaseFile)
|
|||
return convertResultCode(srv);
|
||||
}
|
||||
|
||||
// Properly wrap the database handle's mutex.
|
||||
mDBMutex.initWithMutex(sqlite3_db_mutex(mDBConn));
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
if (!gStorageLog)
|
||||
gStorageLog = ::PR_NewLogModule("mozStorage");
|
||||
|
@ -439,7 +444,7 @@ Connection::databaseElementExists(enum DatabaseElementType aElementType,
|
|||
bool
|
||||
Connection::findFunctionByInstance(nsISupports *aInstance)
|
||||
{
|
||||
mDBMutex.assertCurrentThreadOwns();
|
||||
PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(mFunctionsMutex);
|
||||
FFEArguments args = { aInstance, false };
|
||||
mFunctions.EnumerateRead(findFunctionEnumerator, &args);
|
||||
return args.found;
|
||||
|
@ -455,7 +460,7 @@ Connection::sProgressHelper(void *aArg)
|
|||
int
|
||||
Connection::progressHandler()
|
||||
{
|
||||
mDBMutex.assertCurrentThreadOwns();
|
||||
nsAutoLock mutex(mProgressHandlerMutex);
|
||||
if (mProgressHandler) {
|
||||
PRBool result;
|
||||
nsresult rv = mProgressHandler->OnProgress(this, &result);
|
||||
|
@ -507,6 +512,12 @@ Connection::Close()
|
|||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
nsAutoLock mutex(mProgressHandlerMutex);
|
||||
if (mProgressHandler)
|
||||
::sqlite3_progress_handler(mDBConn, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int srv = ::sqlite3_close(mDBConn);
|
||||
NS_ASSERTION(srv == SQLITE_OK,
|
||||
"sqlite3_close failed. There are probably outstanding statements that are listed above!");
|
||||
|
@ -630,45 +641,42 @@ Connection::ExecuteAsync(mozIStorageStatement **aStatements,
|
|||
{
|
||||
int rc = SQLITE_OK;
|
||||
nsTArray<StatementData> stmts(aNumStatements);
|
||||
{
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
for (PRUint32 i = 0; i < aNumStatements && rc == SQLITE_OK; i++) {
|
||||
sqlite3_stmt *old_stmt =
|
||||
static_cast<Statement *>(aStatements[i])->nativeStatement();
|
||||
if (!old_stmt) {
|
||||
rc = SQLITE_MISUSE;
|
||||
break;
|
||||
}
|
||||
NS_ASSERTION(::sqlite3_db_handle(old_stmt) == mDBConn,
|
||||
"Statement must be from this database connection!");
|
||||
for (PRUint32 i = 0; i < aNumStatements && rc == SQLITE_OK; i++) {
|
||||
sqlite3_stmt *old_stmt =
|
||||
static_cast<Statement *>(aStatements[i])->nativeStatement();
|
||||
if (!old_stmt) {
|
||||
rc = SQLITE_MISUSE;
|
||||
break;
|
||||
}
|
||||
NS_ASSERTION(::sqlite3_db_handle(old_stmt) == mDBConn,
|
||||
"Statement must be from this database connection!");
|
||||
|
||||
// Clone this statement. We only need a sqlite3_stmt object, so we can
|
||||
// avoid all the extra work that making a new Statement would normally
|
||||
// involve and use the SQLite API.
|
||||
sqlite3_stmt *new_stmt;
|
||||
rc = ::sqlite3_prepare_v2(mDBConn, ::sqlite3_sql(old_stmt), -1, &new_stmt,
|
||||
NULL);
|
||||
if (rc != SQLITE_OK)
|
||||
break;
|
||||
// Clone this statement. We only need a sqlite3_stmt object, so we can
|
||||
// avoid all the extra work that making a new Statement would normally
|
||||
// involve and use the SQLite API.
|
||||
sqlite3_stmt *new_stmt;
|
||||
rc = ::sqlite3_prepare_v2(mDBConn, ::sqlite3_sql(old_stmt), -1, &new_stmt,
|
||||
NULL);
|
||||
if (rc != SQLITE_OK)
|
||||
break;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PR_LOG(gStorageLog, PR_LOG_NOTICE,
|
||||
("Cloned statement 0x%p to 0x%p", old_stmt, new_stmt));
|
||||
PR_LOG(gStorageLog, PR_LOG_NOTICE,
|
||||
("Cloned statement 0x%p to 0x%p", old_stmt, new_stmt));
|
||||
#endif
|
||||
|
||||
// Transfer the bindings
|
||||
rc = sqlite3_transfer_bindings(old_stmt, new_stmt);
|
||||
if (rc != SQLITE_OK)
|
||||
break;
|
||||
// Transfer the bindings
|
||||
rc = sqlite3_transfer_bindings(old_stmt, new_stmt);
|
||||
if (rc != SQLITE_OK)
|
||||
break;
|
||||
|
||||
Statement *storageStmt = static_cast<Statement *>(aStatements[i]);
|
||||
StatementData data(new_stmt, storageStmt->bindingParamsArray());
|
||||
if (!stmts.AppendElement(data)) {
|
||||
rc = SQLITE_NOMEM;
|
||||
break;
|
||||
}
|
||||
} // for loop
|
||||
} // locked Scope
|
||||
Statement *storageStmt = static_cast<Statement *>(aStatements[i]);
|
||||
StatementData data(new_stmt, storageStmt->bindingParamsArray());
|
||||
if (!stmts.AppendElement(data)) {
|
||||
rc = SQLITE_NOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch to the background
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -685,11 +693,8 @@ Connection::ExecuteAsync(mozIStorageStatement **aStatements,
|
|||
}
|
||||
|
||||
// Always reset all the statements
|
||||
{
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
for (PRUint32 i = 0; i < aNumStatements; i++)
|
||||
(void)aStatements[i]->Reset();
|
||||
}
|
||||
for (PRUint32 i = 0; i < aNumStatements; i++)
|
||||
(void)aStatements[i]->Reset();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -711,7 +716,7 @@ Connection::IndexExists(const nsACString &aIndexName,
|
|||
NS_IMETHODIMP
|
||||
Connection::GetTransactionInProgress(PRBool *_inProgress)
|
||||
{
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mTransactionMutex);
|
||||
*_inProgress = mTransactionInProgress;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -725,7 +730,7 @@ Connection::BeginTransaction()
|
|||
NS_IMETHODIMP
|
||||
Connection::BeginTransactionAs(PRInt32 aTransactionType)
|
||||
{
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mTransactionMutex);
|
||||
if (mTransactionInProgress)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv;
|
||||
|
@ -750,7 +755,7 @@ Connection::BeginTransactionAs(PRInt32 aTransactionType)
|
|||
NS_IMETHODIMP
|
||||
Connection::CommitTransaction()
|
||||
{
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mTransactionMutex);
|
||||
if (!mTransactionInProgress)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv = ExecuteSimpleSQL(NS_LITERAL_CSTRING("COMMIT TRANSACTION"));
|
||||
|
@ -762,7 +767,7 @@ Connection::CommitTransaction()
|
|||
NS_IMETHODIMP
|
||||
Connection::RollbackTransaction()
|
||||
{
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mTransactionMutex);
|
||||
if (!mTransactionInProgress)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv = ExecuteSimpleSQL(NS_LITERAL_CSTRING("ROLLBACK TRANSACTION"));
|
||||
|
@ -796,7 +801,7 @@ Connection::CreateFunction(const nsACString &aFunctionName,
|
|||
|
||||
// Check to see if this function is already defined. We only check the name
|
||||
// because a function can be defined with the same body but different names.
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mFunctionsMutex);
|
||||
NS_ENSURE_FALSE(mFunctions.Get(aFunctionName, NULL), NS_ERROR_FAILURE);
|
||||
|
||||
int srv = ::sqlite3_create_function(mDBConn,
|
||||
|
@ -824,7 +829,7 @@ Connection::CreateAggregateFunction(const nsACString &aFunctionName,
|
|||
if (!mDBConn) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Check to see if this function name is already defined.
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mFunctionsMutex);
|
||||
NS_ENSURE_FALSE(mFunctions.Get(aFunctionName, NULL), NS_ERROR_FAILURE);
|
||||
|
||||
// Because aggregate functions depend on state across calls, you cannot have
|
||||
|
@ -854,7 +859,7 @@ Connection::RemoveFunction(const nsACString &aFunctionName)
|
|||
{
|
||||
if (!mDBConn) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mFunctionsMutex);
|
||||
NS_ENSURE_TRUE(mFunctions.Get(aFunctionName, NULL), NS_ERROR_FAILURE);
|
||||
|
||||
int srv = ::sqlite3_create_function(mDBConn,
|
||||
|
@ -881,7 +886,7 @@ Connection::SetProgressHandler(PRInt32 aGranularity,
|
|||
if (!mDBConn) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Return previous one
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mProgressHandlerMutex);
|
||||
NS_IF_ADDREF(*_oldHandler = mProgressHandler);
|
||||
|
||||
if (!aHandler || aGranularity <= 0) {
|
||||
|
@ -900,7 +905,7 @@ Connection::RemoveProgressHandler(mozIStorageProgressHandler **_oldHandler)
|
|||
if (!mDBConn) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Return previous one
|
||||
SQLiteMutexAutoLock lockedScope(mDBMutex);
|
||||
nsAutoLock mutex(mProgressHandlerMutex);
|
||||
NS_IF_ADDREF(*_oldHandler = mProgressHandler);
|
||||
|
||||
mProgressHandler = nsnull;
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "nsString.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "mozIStorageProgressHandler.h"
|
||||
#include "SQLiteMutex.h"
|
||||
#include "mozIStorageConnection.h"
|
||||
#include "mozStorageService.h"
|
||||
|
||||
|
@ -159,27 +158,13 @@ private:
|
|||
*/
|
||||
PRBool mAsyncExecutionThreadShuttingDown;
|
||||
|
||||
/**
|
||||
* Wraps the mutex that SQLite gives us from sqlite3_db_mutex.
|
||||
*/
|
||||
SQLiteMutex mDBMutex;
|
||||
|
||||
/**
|
||||
* Tracks if we have a transaction in progress or not. Access protected by
|
||||
* mDBMutex.
|
||||
*/
|
||||
PRLock *mTransactionMutex;
|
||||
PRBool mTransactionInProgress;
|
||||
|
||||
/**
|
||||
* Stores the mapping of a given function by name to its instance. Access is
|
||||
* protected by mDBMutex.
|
||||
*/
|
||||
PRLock *mFunctionsMutex;
|
||||
nsInterfaceHashtable<nsCStringHashKey, nsISupports> mFunctions;
|
||||
|
||||
/**
|
||||
* Stores the registered progress handler for the database connection. Access
|
||||
* is protected by mDBMutex.
|
||||
*/
|
||||
PRLock *mProgressHandlerMutex;
|
||||
nsCOMPtr<mozIStorageProgressHandler> mProgressHandler;
|
||||
|
||||
// This is here for two reasons: 1) It's used to make sure that the
|
||||
|
|
Загрузка…
Ссылка в новой задаче