mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backout of bug 496019 and bug 526601 due to window build bustage.
This commit is contained in:
parent
ff9260ceaf
commit
116173a4b7
@ -64,7 +64,6 @@ XPIDLSRCS = \
|
||||
mozIStoragePendingStatement.idl \
|
||||
mozIStorageBindingParamsArray.idl \
|
||||
mozIStorageBindingParams.idl \
|
||||
mozIStorageCompletionCallback.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface mozIStorageAggregateFunction;
|
||||
interface mozIStorageCompletionCallback;
|
||||
interface mozIStorageFunction;
|
||||
interface mozIStorageProgressHandler;
|
||||
interface mozIStorageStatement;
|
||||
@ -59,31 +58,17 @@ interface nsIFile;
|
||||
*
|
||||
* @threadsafe
|
||||
*/
|
||||
[scriptable, uuid(5a06b207-1977-47d4-b140-271cb851bb26)]
|
||||
[scriptable, uuid(ac3c486c-69a1-4cbe-8f25-2ad20880eab3)]
|
||||
interface mozIStorageConnection : nsISupports {
|
||||
/*
|
||||
* Initialization and status
|
||||
*/
|
||||
|
||||
/**
|
||||
* Closes a database connection. Callers must finalize all statements created
|
||||
* for this connection prior to calling this method. It is illegal to use
|
||||
* call this method if any asynchronous statements have been executed on this
|
||||
* connection.
|
||||
*
|
||||
* @throws NS_ERROR_UNEXPECTED
|
||||
* If any statement has been executed asynchronously on this object.
|
||||
* Closes a database connection. C++ callers should simply set the database
|
||||
* variable to NULL.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Asynchronously closes a database connection, allowing all pending
|
||||
* asynchronous statements to complete first.
|
||||
*
|
||||
* @param aCallback [optional]
|
||||
* A callback that will be notified when the close is completed.
|
||||
*/
|
||||
void asyncClose([optional] in mozIStorageCompletionCallback aCallback);
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Indicates if the connection is open and ready to use. This will be false
|
||||
|
@ -190,7 +190,7 @@ AsyncExecuteStatements::execute(StatementDataArray &aStatements,
|
||||
nsresult rv = target->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Return it as the pending statement object and track it.
|
||||
// Return it as the pending statement object
|
||||
NS_ADDREF(*_stmt = event);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "nsAutoLock.h"
|
||||
|
||||
#include "mozIStorageAggregateFunction.h"
|
||||
#include "mozIStorageCompletionCallback.h"
|
||||
#include "mozIStorageFunction.h"
|
||||
|
||||
#include "mozStorageAsyncStatementExecution.h"
|
||||
@ -239,38 +238,6 @@ aggregateFunctionFinalHelper(sqlite3_context *aCtx)
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Local Classes
|
||||
|
||||
namespace {
|
||||
|
||||
class AsyncCloseConnection : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AsyncCloseConnection(Connection *aConnection,
|
||||
nsIEventTarget *aCallingThread,
|
||||
nsIRunnable *aCallbackEvent)
|
||||
: mConnection(aConnection)
|
||||
, mCallingThread(aCallingThread)
|
||||
, mCallbackEvent(aCallbackEvent)
|
||||
{
|
||||
}
|
||||
|
||||
NS_METHOD Run()
|
||||
{
|
||||
(void)mConnection->internalClose();
|
||||
if (mCallbackEvent)
|
||||
(void)mCallingThread->Dispatch(mCallbackEvent, NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<Connection> mConnection;
|
||||
nsCOMPtr<nsIEventTarget> mCallingThread;
|
||||
nsCOMPtr<nsIRunnable> mCallbackEvent;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@ -280,8 +247,8 @@ private:
|
||||
Connection::Connection(Service *aService)
|
||||
: sharedAsyncExecutionMutex("Connection::sharedAsyncExecutionMutex")
|
||||
, mDBConn(nsnull)
|
||||
, mAsyncExecutionMutex("Connection::mAsyncExecutionMutex")
|
||||
, mAsyncExecutionThreadShuttingDown(false)
|
||||
, mAsyncExecutionMutex(nsAutoLock::NewLock("AsyncExecutionMutex"))
|
||||
, mAsyncExecutionThreadShuttingDown(PR_FALSE)
|
||||
, mTransactionMutex(nsAutoLock::NewLock("TransactionMutex"))
|
||||
, mTransactionInProgress(PR_FALSE)
|
||||
, mFunctionsMutex(nsAutoLock::NewLock("FunctionsMutex"))
|
||||
@ -295,6 +262,7 @@ Connection::Connection(Service *aService)
|
||||
Connection::~Connection()
|
||||
{
|
||||
(void)Close();
|
||||
nsAutoLock::DestroyLock(mAsyncExecutionMutex);
|
||||
nsAutoLock::DestroyLock(mTransactionMutex);
|
||||
nsAutoLock::DestroyLock(mFunctionsMutex);
|
||||
nsAutoLock::DestroyLock(mProgressHandlerMutex);
|
||||
@ -308,7 +276,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(
|
||||
already_AddRefed<nsIEventTarget>
|
||||
Connection::getAsyncExecutionTarget()
|
||||
{
|
||||
MutexAutoLock lockedScope(mAsyncExecutionMutex);
|
||||
nsAutoLock mutex(mAsyncExecutionMutex);
|
||||
|
||||
// If we are shutting down the asynchronous thread, don't hand out any more
|
||||
// references to the thread.
|
||||
@ -332,6 +300,7 @@ nsresult
|
||||
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);
|
||||
@ -501,33 +470,14 @@ Connection::progressHandler()
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Connection::setClosedState()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// mozIStorageConnection
|
||||
|
||||
NS_IMETHODIMP
|
||||
Connection::Close()
|
||||
{
|
||||
// Flag that we are shutting down the async thread, so that
|
||||
// getAsyncExecutionTarget knows not to expose/create the async thread.
|
||||
{
|
||||
MutexAutoLock lockedScope(mAsyncExecutionMutex);
|
||||
NS_ENSURE_FALSE(mAsyncExecutionThreadShuttingDown, NS_ERROR_UNEXPECTED);
|
||||
mAsyncExecutionThreadShuttingDown = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Connection::internalClose()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Sanity checks to make sure we are in the proper state before calling this.
|
||||
NS_ASSERTION(mDBConn, "Database connection is already null!");
|
||||
|
||||
{ // Make sure we have marked our async thread as shutting down.
|
||||
MutexAutoLock lockedScope(mAsyncExecutionMutex);
|
||||
NS_ASSERTION(mAsyncExecutionThreadShuttingDown,
|
||||
"Did not call setClosedState!");
|
||||
}
|
||||
#endif
|
||||
if (!mDBConn)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
nsCAutoString leafName(":memory");
|
||||
@ -537,6 +487,20 @@ Connection::internalClose()
|
||||
leafName.get()));
|
||||
#endif
|
||||
|
||||
// Flag that we are shutting down the async thread, so that
|
||||
// getAsyncExecutionTarget knows not to expose/create the async thread.
|
||||
{
|
||||
nsAutoLock mutex(mAsyncExecutionMutex);
|
||||
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
|
||||
// Notify about any non-finalized statements.
|
||||
sqlite3_stmt *stmt = NULL;
|
||||
@ -548,68 +512,20 @@ Connection::internalClose()
|
||||
}
|
||||
#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!");
|
||||
|
||||
mDBConn = NULL;
|
||||
|
||||
return convertResultCode(srv);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// mozIStorageConnection
|
||||
|
||||
NS_IMETHODIMP
|
||||
Connection::Close()
|
||||
{
|
||||
if (!mDBConn)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
{ // Make sure we have not executed any asynchronous statements.
|
||||
MutexAutoLock lockedScope(mAsyncExecutionMutex);
|
||||
NS_ENSURE_FALSE(mAsyncExecutionThread, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
nsresult rv = setClosedState();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return internalClose();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Connection::AsyncClose(mozIStorageCompletionCallback *aCallback)
|
||||
{
|
||||
if (!mDBConn)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> asyncThread(getAsyncExecutionTarget());
|
||||
NS_ENSURE_TRUE(asyncThread, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsresult rv = setClosedState();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create our callback event if we were given a callback.
|
||||
nsCOMPtr<nsIRunnable> completeEvent;
|
||||
if (aCallback) {
|
||||
completeEvent =
|
||||
new nsRunnableMethod<mozIStorageCompletionCallback, nsresult>(
|
||||
aCallback,
|
||||
&mozIStorageCompletionCallback::Complete
|
||||
);
|
||||
NS_ENSURE_TRUE(completeEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// Create and dispatch our close event to the background thread.
|
||||
nsCOMPtr<nsIRunnable> closeEvent =
|
||||
new AsyncCloseConnection(this, NS_GetCurrentThread(), completeEvent);
|
||||
NS_ENSURE_TRUE(closeEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = asyncThread->Dispatch(closeEvent, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Connection::GetConnectionReady(PRBool *_ready)
|
||||
{
|
||||
|
@ -100,22 +100,9 @@ public:
|
||||
*/
|
||||
Mutex sharedAsyncExecutionMutex;
|
||||
|
||||
/**
|
||||
* Closes the SQLite database, and warns about any non-finalized statements.
|
||||
*/
|
||||
nsresult internalClose();
|
||||
|
||||
private:
|
||||
~Connection();
|
||||
|
||||
/**
|
||||
* Sets the database into a closed state so no further actions can be
|
||||
* performed.
|
||||
*
|
||||
* @note mDBConn is set to NULL in this method.
|
||||
*/
|
||||
nsresult setClosedState();
|
||||
|
||||
/**
|
||||
* Describes a certain primitive type in the database.
|
||||
*
|
||||
@ -153,9 +140,9 @@ private:
|
||||
nsCOMPtr<nsIFile> mDatabaseFile;
|
||||
|
||||
/**
|
||||
* Protects access to mAsyncExecutionThread and mPendingStatements.
|
||||
* Protects access to mAsyncExecutionThread.
|
||||
*/
|
||||
Mutex mAsyncExecutionMutex;
|
||||
PRLock *mAsyncExecutionMutex;
|
||||
|
||||
/**
|
||||
* Lazily created thread for asynchronous statement execution. Consumers
|
||||
@ -169,7 +156,7 @@ private:
|
||||
* references (or to create the thread in the first place). This variable
|
||||
* should be accessed while holding the mAsyncExecutionMutex.
|
||||
*/
|
||||
bool mAsyncExecutionThreadShuttingDown;
|
||||
PRBool mAsyncExecutionThreadShuttingDown;
|
||||
|
||||
PRLock *mTransactionMutex;
|
||||
PRBool mTransactionInProgress;
|
||||
|
@ -236,66 +236,6 @@ function test_multiple_bindings_on_statements()
|
||||
stmts.forEach(function(stmt) stmt.finalize());
|
||||
}
|
||||
|
||||
function test_asyncClose_does_not_complete_before_statements()
|
||||
{
|
||||
let stmt = createStatement("SELECT * FROM sqlite_master");
|
||||
let executed = false;
|
||||
stmt.executeAsync({
|
||||
handleResult: function(aResultSet)
|
||||
{
|
||||
},
|
||||
handleError: function(aError)
|
||||
{
|
||||
print("Error code " + aError.result + " with message '" +
|
||||
aError.message + "' returned.");
|
||||
do_throw("Unexpected error!");
|
||||
},
|
||||
handleCompletion: function(aReason)
|
||||
{
|
||||
print("handleCompletion(" + aReason +
|
||||
") for test_asyncClose_does_not_complete_before_statements");
|
||||
do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
|
||||
executed = true;
|
||||
}
|
||||
});
|
||||
stmt.finalize();
|
||||
|
||||
getOpenedDatabase().asyncClose(function() {
|
||||
// Ensure that the statement executed to completion.
|
||||
do_check_true(executed);
|
||||
|
||||
// Reset gDBConn so that later tests will get a new connection object.
|
||||
gDBConn = null;
|
||||
run_next_test();
|
||||
});
|
||||
}
|
||||
|
||||
function test_asyncClose_does_not_throw_no_callback()
|
||||
{
|
||||
getOpenedDatabase().asyncClose();
|
||||
|
||||
// Reset gDBConn so that later tests will get a new connection object.
|
||||
gDBConn = null;
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_double_asyncClose_throws()
|
||||
{
|
||||
let conn = getOpenedDatabase();
|
||||
conn.asyncClose();
|
||||
try {
|
||||
conn.asyncClose();
|
||||
do_throw("should have thrown");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
// Reset gDBConn so that later tests will get a new connection object.
|
||||
gDBConn = null;
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Runner
|
||||
|
||||
@ -304,33 +244,18 @@ let tests =
|
||||
test_create_and_add,
|
||||
test_transaction_created,
|
||||
test_multiple_bindings_on_statements,
|
||||
test_asyncClose_does_not_complete_before_statements,
|
||||
test_asyncClose_does_not_throw_no_callback,
|
||||
test_double_asyncClose_throws,
|
||||
];
|
||||
let index = 0;
|
||||
|
||||
function run_next_test()
|
||||
{
|
||||
function _run_next_test() {
|
||||
if (index < tests.length) {
|
||||
do_test_pending();
|
||||
print("Running the next test: " + tests[index].name);
|
||||
|
||||
// Asynchronous tests means that exceptions don't kill the test.
|
||||
try {
|
||||
tests[index++]();
|
||||
}
|
||||
catch (e) {
|
||||
do_throw(e);
|
||||
}
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
if (index < tests.length) {
|
||||
do_test_pending();
|
||||
print("Running the next test: " + tests[index].name);
|
||||
tests[index++]();
|
||||
}
|
||||
|
||||
// For saner stacks, we execute this code RSN.
|
||||
do_execute_soon(_run_next_test);
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
function run_test()
|
||||
|
@ -49,7 +49,6 @@ function test_connectionReady_open()
|
||||
|
||||
var msc = getOpenedDatabase();
|
||||
do_check_true(msc.connectionReady);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_connectionReady_closed()
|
||||
@ -60,28 +59,24 @@ function test_connectionReady_closed()
|
||||
msc.close();
|
||||
do_check_false(msc.connectionReady);
|
||||
gDBConn = null; // this is so later tests don't start to fail.
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_databaseFile()
|
||||
{
|
||||
var msc = getOpenedDatabase();
|
||||
do_check_true(getTestDB().equals(msc.databaseFile));
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_tableExists_not_created()
|
||||
{
|
||||
var msc = getOpenedDatabase();
|
||||
do_check_false(msc.tableExists("foo"));
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_indexExists_not_created()
|
||||
{
|
||||
var msc = getOpenedDatabase();
|
||||
do_check_false(msc.indexExists("foo"));
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_createTable_not_created()
|
||||
@ -89,7 +84,6 @@ function test_createTable_not_created()
|
||||
var msc = getOpenedDatabase();
|
||||
msc.createTable("test", "id INTEGER PRIMARY KEY, name TEXT");
|
||||
do_check_true(msc.tableExists("test"));
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_indexExists_created()
|
||||
@ -97,7 +91,6 @@ function test_indexExists_created()
|
||||
var msc = getOpenedDatabase();
|
||||
msc.executeSimpleSQL("CREATE INDEX name_ind ON test (name)");
|
||||
do_check_true(msc.indexExists("name_ind"));
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_createTable_already_created()
|
||||
@ -110,7 +103,6 @@ function test_createTable_already_created()
|
||||
} catch (e) {
|
||||
do_check_eq(Cr.NS_ERROR_FAILURE, e.result);
|
||||
}
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_lastInsertRowID()
|
||||
@ -118,14 +110,12 @@ function test_lastInsertRowID()
|
||||
var msc = getOpenedDatabase();
|
||||
msc.executeSimpleSQL("INSERT INTO test (name) VALUES ('foo')");
|
||||
do_check_eq(1, msc.lastInsertRowID);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_transactionInProgress_no()
|
||||
{
|
||||
var msc = getOpenedDatabase();
|
||||
do_check_false(msc.transactionInProgress);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_transactionInProgress_yes()
|
||||
@ -140,7 +130,6 @@ function test_transactionInProgress_yes()
|
||||
do_check_true(msc.transactionInProgress);
|
||||
msc.rollbackTransaction();
|
||||
do_check_false(msc.transactionInProgress);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_commitTransaction_no_transaction()
|
||||
@ -153,7 +142,6 @@ function test_commitTransaction_no_transaction()
|
||||
} catch (e) {
|
||||
do_check_eq(Cr.NS_ERROR_FAILURE, e.result);
|
||||
}
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_rollbackTransaction_no_transaction()
|
||||
@ -166,13 +154,11 @@ function test_rollbackTransaction_no_transaction()
|
||||
} catch (e) {
|
||||
do_check_eq(Cr.NS_ERROR_FAILURE, e.result);
|
||||
}
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_get_schemaVersion_not_set()
|
||||
{
|
||||
do_check_eq(0, getOpenedDatabase().schemaVersion);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_set_schemaVersion()
|
||||
@ -181,7 +167,6 @@ function test_set_schemaVersion()
|
||||
const version = 1;
|
||||
msc.schemaVersion = version;
|
||||
do_check_eq(version, msc.schemaVersion);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_set_schemaVersion_same()
|
||||
@ -190,7 +175,6 @@ function test_set_schemaVersion_same()
|
||||
const version = 1;
|
||||
msc.schemaVersion = version; // should still work ok
|
||||
do_check_eq(version, msc.schemaVersion);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_set_schemaVersion_negative()
|
||||
@ -199,7 +183,6 @@ function test_set_schemaVersion_negative()
|
||||
const version = -1;
|
||||
msc.schemaVersion = version;
|
||||
do_check_eq(version, msc.schemaVersion);
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_createTable(){
|
||||
@ -215,7 +198,6 @@ function test_createTable(){
|
||||
do_check_true(e.result==Cr.NS_ERROR_NOT_INITIALIZED ||
|
||||
e.result==Cr.NS_ERROR_FAILURE);
|
||||
}
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_defaultSynchronousAtNormal()
|
||||
@ -230,44 +212,10 @@ function test_defaultSynchronousAtNormal()
|
||||
stmt.reset();
|
||||
stmt.finalize();
|
||||
}
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_close_does_not_spin_event_loop()
|
||||
function test_close_succeeds_with_finalized_async_statement()
|
||||
{
|
||||
// We want to make sure that the event loop on the calling thread does not
|
||||
// spin when close is called.
|
||||
let event = {
|
||||
ran: false,
|
||||
run: function()
|
||||
{
|
||||
this.ran = true;
|
||||
},
|
||||
};
|
||||
|
||||
// Post the event before we call close, so it would run if the event loop was
|
||||
// spun during close.
|
||||
let thread = Cc["@mozilla.org/thread-manager;1"].
|
||||
getService(Ci.nsIThreadManager).
|
||||
currentThread;
|
||||
thread.dispatch(event, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
|
||||
// Sanity check, then close the database. Afterwards, we should not have ran!
|
||||
do_check_false(event.ran);
|
||||
getOpenedDatabase().close();
|
||||
do_check_false(event.ran);
|
||||
|
||||
// Reset gDBConn so that later tests will get a new connection object.
|
||||
gDBConn = null;
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function test_asyncClose_succeeds_with_finalized_async_statement()
|
||||
{
|
||||
// XXX this test isn't perfect since we can't totally control when events will
|
||||
// run. If this paticular function fails randomly, it means we have a
|
||||
// real bug.
|
||||
|
||||
// We want to make sure we create a cached async statement to make sure that
|
||||
// when we finalize our statement, we end up finalizing the async one too so
|
||||
// close will succeed.
|
||||
@ -275,35 +223,8 @@ function test_asyncClose_succeeds_with_finalized_async_statement()
|
||||
stmt.executeAsync();
|
||||
stmt.finalize();
|
||||
|
||||
getOpenedDatabase().asyncClose(function() {
|
||||
// Reset gDBConn so that later tests will get a new connection object.
|
||||
gDBConn = null;
|
||||
run_next_test();
|
||||
});
|
||||
}
|
||||
|
||||
function test_close_fails_with_async_statement_ran()
|
||||
{
|
||||
let stmt = createStatement("SELECT * FROM test");
|
||||
stmt.executeAsync();
|
||||
stmt.finalize();
|
||||
|
||||
let db = getOpenedDatabase();
|
||||
try {
|
||||
db.close();
|
||||
do_throw("should have thrown");
|
||||
}
|
||||
catch (e) {
|
||||
do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
finally {
|
||||
// Clean up after ourselves.
|
||||
db.asyncClose(function() {
|
||||
// Reset gDBConn so that later tests will get a new connection object.
|
||||
gDBConn = null;
|
||||
run_next_test();
|
||||
});
|
||||
}
|
||||
// Cleanup calls close, as well as removes the database file.
|
||||
cleanup();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -329,39 +250,13 @@ var tests = [
|
||||
test_set_schemaVersion_negative,
|
||||
test_createTable,
|
||||
test_defaultSynchronousAtNormal,
|
||||
test_close_does_not_spin_event_loop, // must be ran before executeAsync tests
|
||||
test_asyncClose_succeeds_with_finalized_async_statement,
|
||||
test_close_fails_with_async_statement_ran,
|
||||
test_close_succeeds_with_finalized_async_statement,
|
||||
];
|
||||
let index = 0;
|
||||
|
||||
function run_next_test()
|
||||
{
|
||||
function _run_next_test() {
|
||||
if (index < tests.length) {
|
||||
do_test_pending();
|
||||
print("Running the next test: " + tests[index].name);
|
||||
|
||||
// Asynchronous tests means that exceptions don't kill the test.
|
||||
try {
|
||||
tests[index++]();
|
||||
}
|
||||
catch (e) {
|
||||
do_throw(e);
|
||||
}
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
// For saner stacks, we execute this code RSN.
|
||||
do_execute_soon(_run_next_test);
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
for (var i = 0; i < tests.length; i++)
|
||||
tests[i]();
|
||||
|
||||
cleanup();
|
||||
|
||||
do_test_pending();
|
||||
run_next_test();
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ nsPlacesDBFlush.prototype = {
|
||||
// Close the database connection, this was the last sync and we can't
|
||||
// ensure database coherence from now on.
|
||||
this._self._finalizeInternalStatements();
|
||||
this._self._db.asyncClose();
|
||||
this._self._db.close();
|
||||
}
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user