tor-browser

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

IDBRequest.h (7510B)


      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
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_idbrequest_h__
      8 #define mozilla_dom_idbrequest_h__
      9 
     10 #include "ReportInternalError.h"
     11 #include "SafeRefPtr.h"
     12 #include "js/RootingAPI.h"
     13 #include "mozilla/DOMEventTargetHelper.h"
     14 #include "mozilla/EventForwards.h"
     15 #include "mozilla/HoldDropJSObjects.h"
     16 #include "mozilla/SourceLocation.h"
     17 #include "mozilla/dom/DOMException.h"
     18 #include "mozilla/dom/IDBRequestBinding.h"
     19 #include "mozilla/dom/ScriptSettings.h"
     20 #include "nsCycleCollectionParticipant.h"
     21 
     22 #define PRIVATE_IDBREQUEST_IID \
     23  {0xe68901e5, 0x1d50, 0x4ee9, {0xaf, 0x49, 0x90, 0x99, 0x4a, 0xff, 0xc8, 0x39}}
     24 
     25 class nsIGlobalObject;
     26 
     27 namespace mozilla {
     28 
     29 class ErrorResult;
     30 
     31 namespace dom {
     32 
     33 class IDBCursor;
     34 class IDBDatabase;
     35 class IDBFactory;
     36 class IDBIndex;
     37 class IDBObjectStore;
     38 class IDBTransaction;
     39 template <typename>
     40 struct Nullable;
     41 class OwningIDBObjectStoreOrIDBIndexOrIDBCursor;
     42 class StrongWorkerRef;
     43 
     44 namespace detail {
     45 // This class holds the IID for use with NS_GET_IID.
     46 class PrivateIDBRequest {
     47 public:
     48  NS_INLINE_DECL_STATIC_IID(PRIVATE_IDBREQUEST_IID)
     49 };
     50 
     51 }  // namespace detail
     52 
     53 class IDBRequest : public DOMEventTargetHelper {
     54 protected:
     55  // mSourceAsObjectStore and mSourceAsIndex are exclusive and one must always
     56  // be set. mSourceAsCursor is sometimes set also.
     57  RefPtr<IDBObjectStore> mSourceAsObjectStore;
     58  RefPtr<IDBIndex> mSourceAsIndex;
     59  RefPtr<IDBCursor> mSourceAsCursor;
     60 
     61  SafeRefPtr<IDBTransaction> mTransaction;
     62 
     63  JS::Heap<JS::Value> mResultVal;
     64  RefPtr<DOMException> mError;
     65 
     66  JSCallingLocation mCallerLocation;
     67  uint64_t mLoggingSerialNumber;
     68  nsresult mErrorCode;
     69  bool mHaveResultOrErrorCode;
     70 
     71 public:
     72  [[nodiscard]] static MovingNotNull<RefPtr<IDBRequest>> Create(
     73      JSContext* aCx, IDBDatabase* aDatabase,
     74      SafeRefPtr<IDBTransaction> aTransaction);
     75 
     76  [[nodiscard]] static MovingNotNull<RefPtr<IDBRequest>> Create(
     77      JSContext* aCx, IDBObjectStore* aSource, IDBDatabase* aDatabase,
     78      SafeRefPtr<IDBTransaction> aTransaction);
     79 
     80  [[nodiscard]] static MovingNotNull<RefPtr<IDBRequest>> Create(
     81      JSContext* aCx, IDBIndex* aSource, IDBDatabase* aDatabase,
     82      SafeRefPtr<IDBTransaction> aTransaction);
     83 
     84  static uint64_t NextSerialNumber();
     85 
     86  // EventTarget
     87  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
     88 
     89  void GetSource(
     90      Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const;
     91 
     92  void Reset();
     93 
     94  template <typename ResultCallback>
     95  void SetResult(const ResultCallback& aCallback) {
     96    AssertIsOnOwningThread();
     97    MOZ_ASSERT(!mHaveResultOrErrorCode);
     98    MOZ_ASSERT(mResultVal.isUndefined());
     99    MOZ_ASSERT(!mError);
    100 
    101    // Already disconnected from the owner.
    102    if (!GetOwnerGlobal()) {
    103      SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
    104      return;
    105    }
    106 
    107    // See this global is still valid.
    108    if (NS_WARN_IF(NS_FAILED(CheckCurrentGlobalCorrectness()))) {
    109      SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
    110      return;
    111    }
    112 
    113    AutoJSAPI autoJS;
    114    if (!autoJS.Init(GetOwnerGlobal())) {
    115      IDB_WARNING("Failed to initialize AutoJSAPI!");
    116      SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
    117      return;
    118    }
    119 
    120    JSContext* cx = autoJS.cx();
    121 
    122    JS::Rooted<JS::Value> result(cx);
    123    nsresult rv = aCallback(cx, &result);
    124    if (NS_WARN_IF(NS_FAILED(rv))) {
    125      // This can only fail if the structured clone contains a mutable file
    126      // and the child is not in the main thread and main process.
    127      // In that case CreateAndWrapMutableFile() returns false which shows up
    128      // as NS_ERROR_DOM_DATA_CLONE_ERR here.
    129      MOZ_ASSERT(rv == NS_ERROR_DOM_DATA_CLONE_ERR);
    130 
    131      // We are not setting a result or an error object here since we want to
    132      // throw an exception when the 'result' property is being touched.
    133      return;
    134    }
    135 
    136    mError = nullptr;
    137 
    138    mResultVal = result;
    139    mozilla::HoldJSObjects(this);
    140 
    141    mHaveResultOrErrorCode = true;
    142  }
    143 
    144  void SetError(nsresult aRv);
    145 
    146  nsresult GetErrorCode() const
    147 #ifdef DEBUG
    148      ;
    149 #else
    150  {
    151    return mErrorCode;
    152  }
    153 #endif
    154 
    155  DOMException* GetErrorAfterResult() const
    156 #ifdef DEBUG
    157      ;
    158 #else
    159  {
    160    return mError;
    161  }
    162 #endif
    163 
    164  DOMException* GetError(ErrorResult& aRv);
    165 
    166  const JSCallingLocation& GetCallerLocation() const { return mCallerLocation; }
    167 
    168  bool IsPending() const { return !mHaveResultOrErrorCode; }
    169 
    170  uint64_t LoggingSerialNumber() const {
    171    AssertIsOnOwningThread();
    172 
    173    return mLoggingSerialNumber;
    174  }
    175 
    176  void SetLoggingSerialNumber(uint64_t aLoggingSerialNumber);
    177 
    178  nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); }
    179 
    180  void GetResult(JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv) const;
    181 
    182  void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
    183                 ErrorResult& aRv) const {
    184    GetResult(aResult, aRv);
    185  }
    186 
    187  Maybe<IDBTransaction&> MaybeTransactionRef() const {
    188    AssertIsOnOwningThread();
    189 
    190    return mTransaction.maybeDeref();
    191  }
    192 
    193  IDBTransaction& MutableTransactionRef() const {
    194    AssertIsOnOwningThread();
    195 
    196    return *mTransaction;
    197  }
    198 
    199  SafeRefPtr<IDBTransaction> AcquireTransaction() const {
    200    AssertIsOnOwningThread();
    201 
    202    return mTransaction.clonePtr();
    203  }
    204 
    205  // For WebIDL binding.
    206  RefPtr<IDBTransaction> GetTransaction() const {
    207    AssertIsOnOwningThread();
    208 
    209    return AsRefPtr(mTransaction.clonePtr());
    210  }
    211 
    212  IDBRequestReadyState ReadyState() const;
    213 
    214  void SetSource(IDBCursor* aSource);
    215 
    216  IMPL_EVENT_HANDLER(success);
    217  IMPL_EVENT_HANDLER(error);
    218 
    219  void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBRequest); }
    220 
    221  NS_DECL_ISUPPORTS_INHERITED
    222  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
    223                                                         DOMEventTargetHelper)
    224 
    225  // nsWrapperCache
    226  virtual JSObject* WrapObject(JSContext* aCx,
    227                               JS::Handle<JSObject*> aGivenProto) override;
    228 
    229 protected:
    230  explicit IDBRequest(IDBDatabase* aDatabase);
    231  explicit IDBRequest(nsIGlobalObject* aGlobal);
    232  ~IDBRequest();
    233 
    234  void InitMembers();
    235 
    236  void ConstructResult();
    237 };
    238 
    239 class IDBOpenDBRequest final : public IDBRequest {
    240  // Only touched on the owning thread.
    241  SafeRefPtr<IDBFactory> mFactory;
    242 
    243  RefPtr<StrongWorkerRef> mWorkerRef;
    244 
    245  bool mIncreasedActiveDatabaseCount;
    246 
    247 public:
    248  [[nodiscard]] static RefPtr<IDBOpenDBRequest> Create(
    249      JSContext* aCx, SafeRefPtr<IDBFactory> aFactory,
    250      nsIGlobalObject* aGlobal);
    251 
    252  void SetTransaction(SafeRefPtr<IDBTransaction> aTransaction);
    253 
    254  void DispatchNonTransactionError(nsresult aErrorCode);
    255 
    256  void NoteComplete();
    257 
    258  // EventTarget
    259  IMPL_EVENT_HANDLER(blocked);
    260  IMPL_EVENT_HANDLER(upgradeneeded);
    261 
    262  NS_DECL_ISUPPORTS_INHERITED
    263  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest, IDBRequest)
    264 
    265  // nsWrapperCache
    266  virtual JSObject* WrapObject(JSContext* aCx,
    267                               JS::Handle<JSObject*> aGivenProto) override;
    268 
    269 private:
    270  IDBOpenDBRequest(SafeRefPtr<IDBFactory> aFactory, nsIGlobalObject* aGlobal);
    271 
    272  ~IDBOpenDBRequest();
    273 
    274  void IncreaseActiveDatabaseCount();
    275 
    276  void MaybeDecreaseActiveDatabaseCount();
    277 };
    278 
    279 }  // namespace dom
    280 }  // namespace mozilla
    281 
    282 #endif  // mozilla_dom_idbrequest_h__