Bug 1816170 - Disable perftest-on-autoland cron. r=aglavic
[gecko.git] / dom / indexedDB / IDBTransaction.h
blob65fefddfe5f1eae845c8495c5e32b9906683458b
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/. */
7 #ifndef mozilla_dom_idbtransaction_h__
8 #define mozilla_dom_idbtransaction_h__
10 #include "FlippedOnce.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/dom/IDBTransactionBinding.h"
13 #include "mozilla/dom/quota/CheckedUnsafePtr.h"
14 #include "mozilla/DOMEventTargetHelper.h"
15 #include "nsCycleCollectionParticipant.h"
16 #include "nsIRunnable.h"
17 #include "nsString.h"
18 #include "nsTArray.h"
19 #include "SafeRefPtr.h"
21 namespace mozilla {
23 class ErrorResult;
24 class EventChainPreVisitor;
26 namespace dom {
28 class DOMException;
29 class DOMStringList;
30 class IDBCursor;
31 class IDBDatabase;
32 class IDBObjectStore;
33 class IDBOpenDBRequest;
34 class IDBRequest;
35 class StrongWorkerRef;
37 namespace indexedDB {
38 class PBackgroundIDBCursorChild;
39 class BackgroundRequestChild;
40 class BackgroundTransactionChild;
41 class BackgroundVersionChangeTransactionChild;
42 class IndexMetadata;
43 class ObjectStoreSpec;
44 class OpenCursorParams;
45 class RequestParams;
46 } // namespace indexedDB
48 class IDBTransaction final
49 : public DOMEventTargetHelper,
50 public nsIRunnable,
51 public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
52 friend class indexedDB::BackgroundRequestChild;
54 public:
55 enum struct Mode {
56 ReadOnly = 0,
57 ReadWrite,
58 ReadWriteFlush,
59 Cleanup,
60 VersionChange,
62 // Only needed for IPC serialization helper, should never be used in code.
63 Invalid
66 enum struct ReadyState { Active, Inactive, Committing, Finished };
68 private:
69 // TODO: Only non-const because of Bug 1575173.
70 RefPtr<IDBDatabase> mDatabase;
71 RefPtr<DOMException> mError;
72 const nsTArray<nsString> mObjectStoreNames;
73 nsTArray<RefPtr<IDBObjectStore>> mObjectStores;
74 nsTArray<RefPtr<IDBObjectStore>> mDeletedObjectStores;
75 RefPtr<StrongWorkerRef> mWorkerRef;
76 nsTArray<NotNull<IDBCursor*>> mCursors;
78 // Tagged with mMode. If mMode is Mode::VersionChange then mBackgroundActor
79 // will be a BackgroundVersionChangeTransactionChild. Otherwise it will be a
80 // BackgroundTransactionChild.
81 union {
82 indexedDB::BackgroundTransactionChild* mNormalBackgroundActor;
83 indexedDB::BackgroundVersionChangeTransactionChild*
84 mVersionChangeBackgroundActor;
85 } mBackgroundActor;
87 const int64_t mLoggingSerialNumber;
89 // Only used for Mode::VersionChange transactions.
90 int64_t mNextObjectStoreId;
91 int64_t mNextIndexId;
93 nsresult mAbortCode; ///< The result that caused the transaction to be
94 ///< aborted, or NS_OK if not aborted.
95 ///< NS_ERROR_DOM_INDEXEDDB_ABORT_ERR indicates that the
96 ///< user explicitly requested aborting. Should be
97 ///< renamed to mResult or so, because it is actually
98 ///< used to check if the transaction has been aborted.
99 uint32_t mPendingRequestCount; ///< Counted via OnNewRequest and
100 ///< OnRequestFinished, so that the
101 ///< transaction can auto-commit when the last
102 ///< pending request finished.
104 const nsString mFilename;
105 const uint32_t mLineNo;
106 const uint32_t mColumn;
108 ReadyState mReadyState = ReadyState::Active;
109 FlippedOnce<false> mStarted;
110 const Mode mMode;
112 bool mRegistered; ///< Whether mDatabase->RegisterTransaction() has been
113 ///< called (which may not be the case if construction was
114 ///< incomplete).
115 FlippedOnce<false> mAbortedByScript;
116 bool mNotedActiveTransaction;
117 FlippedOnce<false> mSentCommitOrAbort;
119 #ifdef DEBUG
120 FlippedOnce<false> mFiredCompleteOrAbort;
121 FlippedOnce<false> mWasExplicitlyCommitted;
122 #endif
124 public:
125 [[nodiscard]] static SafeRefPtr<IDBTransaction> CreateVersionChange(
126 IDBDatabase* aDatabase,
127 indexedDB::BackgroundVersionChangeTransactionChild* aActor,
128 NotNull<IDBOpenDBRequest*> aOpenRequest, int64_t aNextObjectStoreId,
129 int64_t aNextIndexId);
131 [[nodiscard]] static SafeRefPtr<IDBTransaction> Create(
132 JSContext* aCx, IDBDatabase* aDatabase,
133 const nsTArray<nsString>& aObjectStoreNames, Mode aMode);
135 static Maybe<IDBTransaction&> MaybeCurrent();
137 void AssertIsOnOwningThread() const
138 #ifdef DEBUG
140 #else
143 #endif
145 void SetBackgroundActor(
146 indexedDB::BackgroundTransactionChild* aBackgroundActor);
148 void ClearBackgroundActor() {
149 AssertIsOnOwningThread();
151 if (mMode == Mode::VersionChange) {
152 mBackgroundActor.mVersionChangeBackgroundActor = nullptr;
153 } else {
154 mBackgroundActor.mNormalBackgroundActor = nullptr;
157 // Note inactive transaction here if we didn't receive the Complete message
158 // from the parent.
159 MaybeNoteInactiveTransaction();
162 indexedDB::BackgroundRequestChild* StartRequest(
163 MovingNotNull<RefPtr<mozilla::dom::IDBRequest>> aRequest,
164 const indexedDB::RequestParams& aParams);
166 void OpenCursor(indexedDB::PBackgroundIDBCursorChild& aBackgroundActor,
167 const indexedDB::OpenCursorParams& aParams);
169 void RefreshSpec(bool aMayDelete);
171 bool IsCommittingOrFinished() const {
172 AssertIsOnOwningThread();
174 return mReadyState == ReadyState::Committing ||
175 mReadyState == ReadyState::Finished;
178 bool IsActive() const {
179 AssertIsOnOwningThread();
181 return mReadyState == ReadyState::Active;
184 bool IsInactive() const {
185 AssertIsOnOwningThread();
187 return mReadyState == ReadyState::Inactive;
190 bool IsFinished() const {
191 AssertIsOnOwningThread();
193 return mReadyState == ReadyState::Finished;
196 bool IsWriteAllowed() const {
197 AssertIsOnOwningThread();
198 return mMode == Mode::ReadWrite || mMode == Mode::ReadWriteFlush ||
199 mMode == Mode::Cleanup || mMode == Mode::VersionChange;
202 bool IsAborted() const {
203 AssertIsOnOwningThread();
204 return NS_FAILED(mAbortCode);
207 #ifdef DEBUG
208 bool WasExplicitlyCommitted() const { return mWasExplicitlyCommitted; }
209 #endif
211 void TransitionToActive() {
212 MOZ_ASSERT(mReadyState == ReadyState::Inactive);
213 mReadyState = ReadyState::Active;
216 void TransitionToInactive() {
217 MOZ_ASSERT(mReadyState == ReadyState::Active);
218 mReadyState = ReadyState::Inactive;
221 nsresult AbortCode() const {
222 AssertIsOnOwningThread();
223 return mAbortCode;
226 void GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo,
227 uint32_t* aColumn) const;
229 // 'Get' prefix is to avoid name collisions with the enum
230 Mode GetMode() const {
231 AssertIsOnOwningThread();
232 return mMode;
235 uint32_t GetPendingRequestCount() const { return mPendingRequestCount; }
237 IDBDatabase* Database() const {
238 AssertIsOnOwningThread();
239 return mDatabase;
242 // Only for use by ProfilerHelpers.h
243 const nsTArray<nsString>& ObjectStoreNamesInternal() const {
244 AssertIsOnOwningThread();
245 return mObjectStoreNames;
248 [[nodiscard]] RefPtr<IDBObjectStore> CreateObjectStore(
249 indexedDB::ObjectStoreSpec& aSpec);
251 void DeleteObjectStore(int64_t aObjectStoreId);
253 void RenameObjectStore(int64_t aObjectStoreId, const nsAString& aName) const;
255 void CreateIndex(IDBObjectStore* aObjectStore,
256 const indexedDB::IndexMetadata& aMetadata) const;
258 void DeleteIndex(IDBObjectStore* aObjectStore, int64_t aIndexId) const;
260 void RenameIndex(IDBObjectStore* aObjectStore, int64_t aIndexId,
261 const nsAString& aName) const;
263 void Abort(IDBRequest* aRequest);
265 void Abort(nsresult aErrorCode);
267 int64_t LoggingSerialNumber() const {
268 AssertIsOnOwningThread();
270 return mLoggingSerialNumber;
273 nsIGlobalObject* GetParentObject() const;
275 void FireCompleteOrAbortEvents(nsresult aResult);
277 // Only for Mode::VersionChange transactions.
278 int64_t NextObjectStoreId();
280 // Only for Mode::VersionChange transactions.
281 int64_t NextIndexId();
283 void InvalidateCursorCaches();
284 void RegisterCursor(IDBCursor& aCursor);
285 void UnregisterCursor(IDBCursor& aCursor);
287 NS_DECL_ISUPPORTS_INHERITED
288 NS_DECL_NSIRUNNABLE
289 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, DOMEventTargetHelper)
291 void CommitIfNotStarted();
293 // nsWrapperCache
294 JSObject* WrapObject(JSContext* aCx,
295 JS::Handle<JSObject*> aGivenProto) override;
297 // Methods bound via WebIDL.
298 IDBDatabase* Db() const { return Database(); }
300 IDBTransactionMode GetMode(ErrorResult& aRv) const;
302 DOMException* GetError() const;
304 [[nodiscard]] RefPtr<IDBObjectStore> ObjectStore(const nsAString& aName,
305 ErrorResult& aRv);
307 void Commit(ErrorResult& aRv);
309 void Abort(ErrorResult& aRv);
311 IMPL_EVENT_HANDLER(abort)
312 IMPL_EVENT_HANDLER(complete)
313 IMPL_EVENT_HANDLER(error)
315 [[nodiscard]] RefPtr<DOMStringList> ObjectStoreNames() const;
317 // EventTarget
318 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
320 private:
321 struct CreatedFromFactoryFunction {};
323 public:
324 IDBTransaction(IDBDatabase* aDatabase,
325 const nsTArray<nsString>& aObjectStoreNames, Mode aMode,
326 nsString aFilename, uint32_t aLineNo, uint32_t aColumn,
327 CreatedFromFactoryFunction aDummy);
329 private:
330 ~IDBTransaction();
332 void AbortInternal(nsresult aAbortCode, RefPtr<DOMException> aError);
334 void SendCommit(bool aAutoCommit);
336 void SendAbort(nsresult aResultCode);
338 void NoteActiveTransaction();
340 void MaybeNoteInactiveTransaction();
342 // TODO consider making private again, or move to the right place
343 public:
344 void OnNewRequest();
346 void OnRequestFinished(bool aRequestCompletedSuccessfully);
348 private:
349 template <typename Func>
350 auto DoWithTransactionChild(const Func& aFunc) const;
352 bool HasTransactionChild() const;
355 inline bool ReferenceEquals(const Maybe<IDBTransaction&>& aLHS,
356 const Maybe<IDBTransaction&>& aRHS) {
357 if (aLHS.isNothing() != aRHS.isNothing()) {
358 return false;
360 return aLHS.isNothing() || &aLHS.ref() == &aRHS.ref();
363 } // namespace dom
364 } // namespace mozilla
366 #endif // mozilla_dom_idbtransaction_h__