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/. */
7 #include "OriginOperationBase.h"
9 #include "mozilla/Assertions.h"
10 #include "mozilla/MozPromise.h"
11 #include "mozilla/StaticPrefs_dom.h"
12 #include "mozilla/dom/fs/TargetPtrHolder.h"
13 #include "mozilla/dom/quota/OriginOperationCallbacks.h"
14 #include "mozilla/dom/quota/QuotaManager.h"
15 #include "mozilla/dom/quota/ResultExtensions.h"
17 #include "nsIThread.h"
18 #include "nsThreadUtils.h"
20 namespace mozilla::dom::quota
{
25 void ResolveOrRejectCallback(const BoolPromise::ResolveOrRejectValue
& aValue
,
26 MozPromiseHolder
<T
>& aPromiseHolder
) {
27 if (aPromiseHolder
.IsEmpty()) {
31 if constexpr (std::is_same_v
<T
, ExclusiveBoolPromise
>) {
32 aPromiseHolder
.UseSynchronousTaskDispatch(__func__
);
35 if (aValue
.IsResolve()) {
36 aPromiseHolder
.Resolve(true, __func__
);
38 aPromiseHolder
.Reject(aValue
.RejectValue(), __func__
);
44 OriginOperationBase::OriginOperationBase(
45 MovingNotNull
<RefPtr
<QuotaManager
>>&& aQuotaManager
, const char* aName
)
46 : BackgroundThreadObject(GetCurrentSerialEventTarget()),
47 mQuotaManager(std::move(aQuotaManager
)),
49 #ifdef QM_COLLECTING_OPERATION_TELEMETRY
54 AssertIsOnOwningThread();
57 OriginOperationBase::~OriginOperationBase() { AssertIsOnOwningThread(); }
59 void OriginOperationBase::RunImmediately() {
60 AssertIsOnOwningThread();
62 [self
= RefPtr(this)]() {
63 if (QuotaManager::IsShuttingDown()) {
64 return BoolPromise::CreateAndReject(NS_ERROR_ABORT
, __func__
);
67 QM_TRY(MOZ_TO_RESULT(self
->DoInit(*self
->mQuotaManager
)),
68 CreateAndRejectBoolPromise
);
73 ->Then(GetCurrentSerialEventTarget(), __func__
,
74 [self
= RefPtr(this)](
75 const BoolPromise::ResolveOrRejectValue
& aValue
) {
76 if (aValue
.IsReject()) {
77 return BoolPromise::CreateAndReject(aValue
.RejectValue(),
81 // Give derived classes the occasion to add additional debug
82 // only checks after the opening was successfully finished on
83 // the current thread before passing the work to the IO thread.
84 QM_TRY(MOZ_TO_RESULT(self
->DirectoryOpen()),
85 CreateAndRejectBoolPromise
);
87 return BoolPromise::CreateAndResolve(true, __func__
);
90 ->Then(mQuotaManager
->IOThread(), __func__
,
91 [selfHolder
= fs::TargetPtrHolder(this)](
92 const BoolPromise::ResolveOrRejectValue
& aValue
) {
93 if (aValue
.IsReject()) {
94 return BoolPromise::CreateAndReject(aValue
.RejectValue(),
98 QM_TRY(MOZ_TO_RESULT(selfHolder
->DoDirectoryWork(
99 *selfHolder
->mQuotaManager
)),
100 CreateAndRejectBoolPromise
);
102 uint32_t pauseOnIOThreadMs
= StaticPrefs::
103 dom_quotaManager_originOperations_pauseOnIOThreadMs();
104 if (pauseOnIOThreadMs
> 0) {
105 PR_Sleep(PR_MillisecondsToInterval(pauseOnIOThreadMs
));
108 return BoolPromise::CreateAndResolve(true, __func__
);
111 GetCurrentSerialEventTarget(), __func__
,
113 RefPtr(this)](const BoolPromise::ResolveOrRejectValue
& aValue
) {
114 if (aValue
.IsReject()) {
115 MOZ_ASSERT(NS_SUCCEEDED(self
->mResultCode
));
117 self
->mResultCode
= aValue
.RejectValue();
120 ResolveOrRejectCallback(aValue
, self
->mWillFinishPromiseHolder
);
121 ResolveOrRejectCallback(aValue
, self
->mWillFinishSyncPromiseHolder
);
125 ResolveOrRejectCallback(aValue
, self
->mDidFinishPromiseHolder
);
126 ResolveOrRejectCallback(aValue
, self
->mDidFinishSyncPromiseHolder
);
130 OriginOperationCallbacks
OriginOperationBase::GetCallbacks(
131 const OriginOperationCallbackOptions
& aCallbackOptions
) {
132 AssertIsOnOwningThread();
134 return OriginOperationCallbackHolders::GetCallbacks(aCallbackOptions
);
137 nsresult
OriginOperationBase::DoInit(QuotaManager
& aQuotaManager
) {
138 AssertIsOnOwningThread();
144 nsresult
OriginOperationBase::DirectoryOpen() {
145 AssertIsOnOwningThread();
151 } // namespace mozilla::dom::quota