tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CachingDatabaseConnection.cpp (5857B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/dom/quota/CachingDatabaseConnection.h"
      8 
      9 #include "mozilla/GeckoTrace.h"
     10 #include "mozilla/ProfilerLabels.h"
     11 #include "mozilla/ipc/BackgroundParent.h"
     12 
     13 namespace mozilla::dom::quota {
     14 
     15 CachingDatabaseConnection::CachingDatabaseConnection(
     16    MovingNotNull<nsCOMPtr<mozIStorageConnection>> aStorageConnection)
     17    :
     18 #ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
     19      mOwningEventTarget{nsAutoOwningEventTarget{}},
     20 #endif
     21      mStorageConnection(std::move(aStorageConnection)) {
     22 }
     23 
     24 void CachingDatabaseConnection::LazyInit(
     25    MovingNotNull<nsCOMPtr<mozIStorageConnection>> aStorageConnection) {
     26 #ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
     27  mOwningEventTarget.init();
     28 #endif
     29  mStorageConnection.init(std::move(aStorageConnection));
     30 }
     31 
     32 Result<CachingDatabaseConnection::CachedStatement, nsresult>
     33 CachingDatabaseConnection::GetCachedStatement(const nsACString& aQuery) {
     34  GECKO_TRACE_SCOPE("dom::quota",
     35                    "CachingDatabaseConnection::GetCachedStatement");
     36 
     37  AssertIsOnConnectionThread();
     38  MOZ_ASSERT(!aQuery.IsEmpty());
     39  MOZ_ASSERT(mStorageConnection);
     40 
     41  AUTO_PROFILER_LABEL("CachingDatabaseConnection::GetCachedStatement", DOM);
     42 
     43  QM_TRY_UNWRAP(
     44      auto stmt,
     45      mCachedStatements.TryLookupOrInsertWith(
     46          aQuery, [&]() -> Result<nsCOMPtr<mozIStorageStatement>, nsresult> {
     47            const auto extraInfo = ScopedLogExtraInfo{
     48                ScopedLogExtraInfo::kTagQueryTainted, aQuery};
     49 
     50            QM_TRY_RETURN(
     51                MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(
     52                    nsCOMPtr<mozIStorageStatement>, **mStorageConnection,
     53                    CreateStatement, aQuery),
     54                QM_PROPAGATE,
     55                ([&aQuery,
     56                  &storageConnection = **mStorageConnection](const auto&) {
     57 #ifdef DEBUG
     58                  nsCString msg;
     59                  MOZ_ALWAYS_SUCCEEDS(
     60                      storageConnection.GetLastErrorString(msg));
     61 
     62                  nsAutoCString error =
     63                      "The statement '"_ns + aQuery +
     64                      "' failed to compile with the error message '"_ns + msg +
     65                      "'."_ns;
     66 
     67                  NS_WARNING(error.get());
     68 #else
     69                    (void)aQuery;
     70 #endif
     71                }));
     72          }));
     73 
     74  return CachedStatement{this, std::move(stmt), aQuery};
     75 }
     76 
     77 Result<CachingDatabaseConnection::BorrowedStatement, nsresult>
     78 CachingDatabaseConnection::BorrowCachedStatement(const nsACString& aQuery) {
     79  QM_TRY_UNWRAP(auto cachedStatement, GetCachedStatement(aQuery));
     80 
     81  return cachedStatement.Borrow();
     82 }
     83 
     84 nsresult CachingDatabaseConnection::ExecuteCachedStatement(
     85    const nsACString& aQuery) {
     86  return ExecuteCachedStatement(
     87      aQuery, [](auto&) -> Result<Ok, nsresult> { return Ok{}; });
     88 }
     89 
     90 void CachingDatabaseConnection::Close() {
     91  AssertIsOnConnectionThread();
     92  MOZ_ASSERT(HasStorageConnection());
     93 
     94  AUTO_PROFILER_LABEL("CachingDatabaseConnection::Close", DOM);
     95 
     96  mCachedStatements.Clear();
     97 
     98  MOZ_ALWAYS_SUCCEEDS((*mStorageConnection)->Close());
     99  mStorageConnection.destroy();
    100 
    101  mClosed = true;
    102 }
    103 
    104 #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING)
    105 CachingDatabaseConnection::CachedStatement::CachedStatement()
    106 #  ifdef DEBUG
    107    : mDEBUGConnection(nullptr)
    108 #  endif
    109 {
    110  AssertIsOnConnectionThread();
    111 
    112  MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement);
    113 }
    114 
    115 CachingDatabaseConnection::CachedStatement::~CachedStatement() {
    116  AssertIsOnConnectionThread();
    117 
    118  MOZ_COUNT_DTOR(CachingDatabaseConnection::CachedStatement);
    119 }
    120 #endif
    121 
    122 CachingDatabaseConnection::CachedStatement::operator bool() const {
    123  AssertIsOnConnectionThread();
    124 
    125  return mStatement;
    126 }
    127 
    128 mozIStorageStatement& CachingDatabaseConnection::BorrowedStatement::operator*()
    129    const {
    130  return *operator->();
    131 }
    132 
    133 mozIStorageStatement* CachingDatabaseConnection::BorrowedStatement::operator->()
    134    const {
    135  MOZ_ASSERT(mStatement);
    136 
    137  return mStatement;
    138 }
    139 
    140 CachingDatabaseConnection::BorrowedStatement
    141 CachingDatabaseConnection::CachedStatement::Borrow() const {
    142  AssertIsOnConnectionThread();
    143 
    144 #ifdef QM_SCOPED_LOG_EXTRA_INFO_ENABLED
    145  return BorrowedStatement{WrapNotNull(mStatement), mQuery};
    146 #else
    147  return BorrowedStatement{WrapNotNull(mStatement)};
    148 #endif
    149 }
    150 
    151 CachingDatabaseConnection::CachedStatement::CachedStatement(
    152    CachingDatabaseConnection* aConnection,
    153    nsCOMPtr<mozIStorageStatement> aStatement, const nsACString& aQuery)
    154    : mStatement(std::move(aStatement))
    155 #ifdef QM_SCOPED_LOG_EXTRA_INFO_ENABLED
    156      ,
    157      mQuery(aQuery)
    158 #endif
    159 #if defined(DEBUG)
    160      ,
    161      mDEBUGConnection(aConnection)
    162 #endif
    163 {
    164 #ifdef DEBUG
    165  MOZ_ASSERT(aConnection);
    166  aConnection->AssertIsOnConnectionThread();
    167 #endif
    168  MOZ_ASSERT(mStatement);
    169  AssertIsOnConnectionThread();
    170 
    171  MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement);
    172 }
    173 
    174 void CachingDatabaseConnection::CachedStatement::AssertIsOnConnectionThread()
    175    const {
    176 #ifdef DEBUG
    177  if (mDEBUGConnection) {
    178    mDEBUGConnection->AssertIsOnConnectionThread();
    179  }
    180  MOZ_ASSERT(!NS_IsMainThread());
    181  MOZ_ASSERT(!mozilla::ipc::IsOnBackgroundThread());
    182 #endif
    183 }
    184 
    185 Result<CachingDatabaseConnection::BorrowedStatement, nsresult>
    186 CachingDatabaseConnection::LazyStatement::Borrow() {
    187  if (!mCachedStatement) {
    188    QM_TRY(Initialize());
    189  }
    190 
    191  return mCachedStatement.Borrow();
    192 }
    193 
    194 Result<Ok, nsresult> CachingDatabaseConnection::LazyStatement::Initialize() {
    195  QM_TRY_UNWRAP(mCachedStatement, mConnection.GetCachedStatement(mQueryString));
    196  return Ok{};
    197 }
    198 
    199 }  // namespace mozilla::dom::quota