Quelle StorageBaseStatementInternal.cpp
Sprache: C
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: sw=2 ts=2 sts=2 expandtab * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//////////////////////////////////////////////////////////////////////////////// //// Local Classes
/** * Used to finalize an asynchronous statement on the background thread.
*/ class AsyncStatementFinalizer : public Runnable { public: /** * Constructor for the event. * * @param aStatement * We need the AsyncStatement to be able to get at the sqlite3_stmt; * we only access/create it on the async event target. * @param aConnection * We need the connection to know what event target to release the * statement on. We release the statement on that event target since * releasing the statement might end up releasing the connection too.
*/
AsyncStatementFinalizer(StorageBaseStatementInternal* aStatement,
Connection* aConnection)
: Runnable("storage::AsyncStatementFinalizer"),
mStatement(aStatement),
mConnection(aConnection) {}
/** * Finalize a sqlite3_stmt on the background thread for a statement whose * destructor was invoked and the statement was non-null.
*/ class LastDitchSqliteStatementFinalizer : public Runnable { public: /** * Event constructor. * * @param aConnection * Used to keep the connection alive. If we failed to do this, it * is possible that the statement going out of scope invoking us * might have the last reference to the connection and so trigger * an attempt to close the connection which is doomed to fail * (because the asynchronous execution event target must exist which * will trigger the failure case). * @param aStatement * The sqlite3_stmt to finalize. This object takes ownership / * responsibility for the instance and all other references to it * should be forgotten.
*/
LastDitchSqliteStatementFinalizer(RefPtr<Connection>& aConnection,
sqlite3_stmt* aStatement)
: Runnable("storage::LastDitchSqliteStatementFinalizer"),
mConnection(aConnection),
mAsyncStatement(aStatement) {
MOZ_ASSERT(aConnection, "You must provide a Connection");
}
void StorageBaseStatementInternal::asyncFinalize() {
nsIEventTarget* target = mDBConnection->getAsyncExecutionTarget(); if (target) { // Attempt to finalize asynchronously
nsCOMPtr<nsIRunnable> event = new AsyncStatementFinalizer(this, mDBConnection);
// Dispatch. Note that dispatching can fail, typically if // we have a race condition with asyncClose(). It's ok, // let asyncClose() win.
(void)target->Dispatch(event, NS_DISPATCH_NORMAL);
} // If we cannot get the background thread, // mozStorageConnection::AsyncClose() has already been called and // the statement either has been or will be cleaned up by // internalClose().
}
void StorageBaseStatementInternal::destructorAsyncFinalize() { if (!mAsyncStatement) return;
if (IsOnCurrentSerialEventTarget(mDBConnection->eventTargetOpenedOn)) { // If we are the owning event target (currently that means we're also the // main thread), then we can get the async target and just dispatch to it.
nsIEventTarget* target = mDBConnection->getAsyncExecutionTarget(); if (target) {
nsCOMPtr<nsIRunnable> event = new LastDitchSqliteStatementFinalizer(mDBConnection, mAsyncStatement);
(void)target->Dispatch(event, NS_DISPATCH_NORMAL);
}
} else { // If we're not the owning event target, assume we're the async event // target, and just run the statement.
nsCOMPtr<nsIRunnable> event = new LastDitchSqliteStatementFinalizer(mDBConnection, mAsyncStatement);
(void)event->Run();
}
// We might not be able to dispatch to the background thread, // presumably because it is being shutdown. Since said shutdown will // finalize the statement, we just need to clean-up around here.
mAsyncStatement = nullptr;
}
NS_IMETHODIMP
StorageBaseStatementInternal::ExecuteAsync(
mozIStorageStatementCallback* aCallback,
mozIStoragePendingStatement** _stmt) { // We used to call Connection::ExecuteAsync but it takes a // mozIStorageBaseStatement signature because it is also a public API. Since // our 'this' has no static concept of mozIStorageBaseStatement and Connection // would just QI it back across to a StorageBaseStatementInternal and the // actual logic is very simple, we now roll our own.
nsTArray<StatementData> stmts(1);
StatementData data;
nsresult rv = getAsynchronousStatementData(data);
NS_ENSURE_SUCCESS(rv, rv);
stmts.AppendElement(data);
// Dispatch to the background return AsyncExecuteStatements::execute(std::move(stmts), mDBConnection,
mNativeConnection, aCallback, _stmt);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.