Bug 1914723 - Remove no longer necessary proxy release for Storage variants. r=asuth

`mParamsArray` doesn't need to be released on the main-thread as it doesn't
contain anymore instances of XPCVariant. The variants used are derived from
thread-safe Storage Variant_base.

Differential Revision: https://phabricator.services.mozilla.com/D220100
This commit is contained in:
Marco Bonardo 2024-09-02 16:57:55 +00:00
Родитель 067fcf7514
Коммит d1da59392b
3 изменённых файлов: 30 добавлений и 47 удалений

Просмотреть файл

@ -130,8 +130,9 @@ already_AddRefed<mozIStorageError> BindingParams::bind(
// object with the right message. Note that we special case // object with the right message. Note that we special case
// SQLITE_MISMATCH, but otherwise get the message from SQLite. // SQLITE_MISMATCH, but otherwise get the message from SQLite.
const char* msg = "Could not covert nsIVariant to SQLite type."; const char* msg = "Could not covert nsIVariant to SQLite type.";
if (rc != SQLITE_MISMATCH) if (rc != SQLITE_MISMATCH) {
msg = ::sqlite3_errmsg(::sqlite3_db_handle(aStatement)); msg = ::sqlite3_errmsg(::sqlite3_db_handle(aStatement));
}
nsCOMPtr<mozIStorageError> err(new Error(rc, msg)); nsCOMPtr<mozIStorageError> err(new Error(rc, msg));
return err.forget(); return err.forget();
@ -143,10 +144,6 @@ already_AddRefed<mozIStorageError> BindingParams::bind(
already_AddRefed<mozIStorageError> AsyncBindingParams::bind( already_AddRefed<mozIStorageError> AsyncBindingParams::bind(
sqlite3_stmt* aStatement) { sqlite3_stmt* aStatement) {
// We should bind by index using the super-class if there is nothing in our
// hashtable.
if (!mNamedParameters.Count()) return BindingParams::bind(aStatement);
nsCOMPtr<mozIStorageError> err; nsCOMPtr<mozIStorageError> err;
for (const auto& entry : mNamedParameters) { for (const auto& entry : mNamedParameters) {
@ -162,29 +159,19 @@ already_AddRefed<mozIStorageError> AsyncBindingParams::bind(
nsAutoCString errMsg(key); nsAutoCString errMsg(key);
errMsg.AppendLiteral(" is not a valid named parameter."); errMsg.AppendLiteral(" is not a valid named parameter.");
err = new Error(SQLITE_RANGE, errMsg.get()); err = new Error(SQLITE_RANGE, errMsg.get());
break; return err.forget();
} }
// XPCVariant's AddRef and Release are not thread-safe and so we must not if (mParameters.Length() <= static_cast<uint32_t>(oneIdx - 1)) {
// do anything that would invoke them here on the async thread. As such we mParameters.SetLength(oneIdx - 1);
// can't cram aValue into mParameters using ReplaceObjectAt so that mParameters.AppendElement(entry.GetWeak());
// we can freeload off of the BindingParams::Bind implementation. } else {
int rc = variantToSQLiteT(BindingColumnData(aStatement, oneIdx - 1), mParameters.ReplaceElementAt(oneIdx - 1, entry.GetWeak());
entry.GetWeak());
if (rc != SQLITE_OK) {
// We had an error while trying to bind. Now we need to create an error
// object with the right message. Note that we special case
// SQLITE_MISMATCH, but otherwise get the message from SQLite.
const char* msg = "Could not covert nsIVariant to SQLite type.";
if (rc != SQLITE_MISMATCH) {
msg = ::sqlite3_errmsg(::sqlite3_db_handle(aStatement));
}
err = new Error(rc, msg);
break;
} }
} }
return err.forget(); // Now bind using the super class.
return BindingParams::bind(aStatement);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -208,8 +195,7 @@ AsyncBindingParams::BindByName(const nsACString& aName, nsIVariant* aValue) {
RefPtr<Variant_base> variant = convertVariantToStorageVariant(aValue); RefPtr<Variant_base> variant = convertVariantToStorageVariant(aValue);
if (!variant) return NS_ERROR_UNEXPECTED; if (!variant) return NS_ERROR_UNEXPECTED;
mNamedParameters.InsertOrUpdate(aName, std::move(variant));
mNamedParameters.InsertOrUpdate(aName, nsCOMPtr<nsIVariant>{variant});
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -7,20 +7,16 @@
#ifndef mozStorageBindingParams_h #ifndef mozStorageBindingParams_h
#define mozStorageBindingParams_h #define mozStorageBindingParams_h
#include "nsCOMArray.h"
#include "nsIVariant.h" #include "nsIVariant.h"
#include "nsInterfaceHashtable.h"
#include "mozStorageBindingParamsArray.h"
#include "mozStorageStatement.h" #include "mozStorageStatement.h"
#include "mozStorageAsyncStatement.h" #include "mozStorageAsyncStatement.h"
#include "Variant.h" #include "Variant.h"
#include "nsTHashMap.h"
#include "mozIStorageBindingParams.h" #include "mozIStorageBindingParams.h"
#include "IStorageBindingParamsInternal.h" #include "IStorageBindingParamsInternal.h"
namespace mozilla { namespace mozilla::storage {
namespace storage {
class BindingParams : public mozIStorageBindingParams, class BindingParams : public mozIStorageBindingParams,
public IStorageBindingParamsInternal { public IStorageBindingParamsInternal {
@ -58,9 +54,13 @@ class BindingParams : public mozIStorageBindingParams,
virtual ~BindingParams() {} virtual ~BindingParams() {}
explicit BindingParams(mozIStorageBindingParamsArray* aOwningArray); explicit BindingParams(mozIStorageBindingParamsArray* aOwningArray);
// Note that this is managed as a sparse array, so particular caution should // Note that this is managed as a sparse array, so particular caution should
// be used for out-of-bounds usage. // be used for out-of-bounds usage.
nsTArray<RefPtr<Variant_base> > mParameters; // Variants added to this array must be thread-safe, thus you should not use
// XPCVariant or similar main-thread only implementations.
nsTArray<RefPtr<Variant_base>> mParameters;
bool mLocked; bool mLocked;
private: private:
@ -102,10 +102,11 @@ class AsyncBindingParams : public BindingParams {
virtual ~AsyncBindingParams() {} virtual ~AsyncBindingParams() {}
private: private:
nsInterfaceHashtable<nsCStringHashKey, nsIVariant> mNamedParameters; // Variants added to this array must be thread-safe, thus you should not use
// XPCVariant or similar main-thread only implementations.
nsTHashMap<nsCStringHashKey, RefPtr<Variant_base>> mNamedParameters;
}; };
} // namespace storage } // namespace mozilla::storage
} // namespace mozilla
#endif // mozStorageBindingParams_h #endif // mozStorageBindingParams_h

Просмотреть файл

@ -10,7 +10,6 @@
#include "sqlite3.h" #include "sqlite3.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "MainThreadUtils.h"
#include "mozStorageBindingParamsArray.h" #include "mozStorageBindingParamsArray.h"
#include "mozStorageConnection.h" #include "mozStorageConnection.h"
@ -19,8 +18,7 @@
struct sqlite3_stmt; struct sqlite3_stmt;
namespace mozilla { namespace mozilla::storage {
namespace storage {
class StatementData { class StatementData {
public: public:
@ -41,13 +39,6 @@ class StatementData {
MOZ_ASSERT(mStatementOwner, "Must have a statement owner!"); MOZ_ASSERT(mStatementOwner, "Must have a statement owner!");
} }
StatementData() : mStatement(nullptr), mQueryStatusRecorded(false) {} StatementData() : mStatement(nullptr), mQueryStatusRecorded(false) {}
~StatementData() {
// We need to ensure that mParamsArray is released on the main thread,
// as the binding arguments may be XPConnect values, which are safe
// to release only on the main thread.
NS_ReleaseOnMainThread("StatementData::mParamsArray",
mParamsArray.forget());
}
/** /**
* Return the sqlite statement, fetching it from the storage statement. In * Return the sqlite statement, fetching it from the storage statement. In
@ -127,7 +118,13 @@ class StatementData {
private: private:
sqlite3_stmt* mStatement; sqlite3_stmt* mStatement;
/**
* It's safe to release this on any thread, as it holds `BindingParams` that
* can only contain thread-safe derivates of `Variant_base`.
*/
RefPtr<BindingParamsArray> mParamsArray; RefPtr<BindingParamsArray> mParamsArray;
bool mQueryStatusRecorded; bool mQueryStatusRecorded;
/** /**
@ -137,7 +134,6 @@ class StatementData {
nsCOMPtr<StorageBaseStatementInternal> mStatementOwner; nsCOMPtr<StorageBaseStatementInternal> mStatementOwner;
}; };
} // namespace storage } // namespace mozilla::storage
} // namespace mozilla
#endif // mozStorageStatementData_h #endif // mozStorageStatementData_h