Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / locks / LockRequestChild.cpp
blob51731c5eed45573b82c1d6fae3dbef278e350747
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 "LockManagerChild.h"
8 #include "LockRequestChild.h"
10 #include "mozilla/dom/Promise.h"
11 #include "mozilla/dom/WorkerPrivate.h"
13 namespace mozilla::dom::locks {
15 using IPCResult = mozilla::ipc::IPCResult;
17 NS_IMPL_ISUPPORTS(LockRequestChild, nsISupports)
19 MOZ_CAN_RUN_SCRIPT static void RunCallbackAndSettlePromise(
20 LockGrantedCallback& aCallback, mozilla::dom::Lock* lock,
21 Promise& aPromise) {
22 ErrorResult rv;
23 if (RefPtr<Promise> result = aCallback.Call(
24 lock, rv, nullptr, CallbackObject::eRethrowExceptions)) {
25 aPromise.MaybeResolve(result);
26 } else if (rv.Failed() && !rv.IsUncatchableException()) {
27 aPromise.MaybeReject(std::move(rv));
28 return;
29 } else {
30 aPromise.MaybeResolveWithUndefined();
32 // This is required even with no failure. IgnoredErrorResult is not an option
33 // since MaybeReject does not accept it.
34 rv.WouldReportJSException();
35 if (NS_WARN_IF(rv.IsUncatchableException())) {
36 rv.SuppressException(); // XXX: Why does this happen anyway?
38 MOZ_ASSERT(!rv.Failed());
41 LockRequestChild::LockRequestChild(
42 const LockRequest& aRequest,
43 const Optional<OwningNonNull<AbortSignal>>& aSignal)
44 : mRequest(aRequest) {
45 if (aSignal.WasPassed()) {
46 Follow(&aSignal.Value());
50 void LockRequestChild::MaybeSetWorkerRef() {
51 if (!NS_IsMainThread()) {
52 mWorkerRef = StrongWorkerRef::Create(
53 GetCurrentThreadWorkerPrivate(), "LockManager",
54 [self = RefPtr(this)]() { self->mWorkerRef = nullptr; });
58 void LockRequestChild::ActorDestroy(ActorDestroyReason aReason) {
59 CastedManager()->NotifyRequestDestroy();
62 IPCResult LockRequestChild::RecvResolve(const LockMode& aLockMode,
63 bool aIsAvailable) {
64 Unfollow();
66 RefPtr<Lock> lock;
67 RefPtr<Promise> promise;
68 if (aIsAvailable) {
69 IgnoredErrorResult err;
70 lock = new Lock(CastedManager()->GetParentObject(), this, mRequest.mName,
71 aLockMode, mRequest.mPromise, err);
72 if (MOZ_UNLIKELY(err.Failed())) {
73 mRequest.mPromise->MaybeRejectWithUnknownError(
74 "Failed to allocate a lock");
75 return IPC_OK();
77 lock->GetWaitingPromise().AppendNativeHandler(lock);
78 promise = &lock->GetWaitingPromise();
79 } else {
80 // We are in `ifAvailable: true` mode and the lock is not available.
81 // There is no waitingPromise since there is no lock, so settle the promise
82 // from the request instead.
83 // This matches "If ifAvailable is true and request is not grantable" step.
84 promise = mRequest.mPromise;
87 // XXX(krosylight): MOZ_KnownLive shouldn't be needed here, mRequest is const
88 RunCallbackAndSettlePromise(MOZ_KnownLive(*mRequest.mCallback), lock,
89 *promise);
90 return IPC_OK();
93 IPCResult LockRequestChild::Recv__delete__(bool aAborted) {
94 MOZ_ASSERT(aAborted, "__delete__ is currently only for abort");
95 Unfollow();
96 mRequest.mPromise->MaybeRejectWithAbortError("The lock request is aborted");
97 return IPC_OK();
100 void LockRequestChild::RunAbortAlgorithm() {
101 AutoJSAPI jsapi;
102 if (NS_WARN_IF(
103 !jsapi.Init(static_cast<AbortSignal*>(Signal())->GetOwnerGlobal()))) {
104 mRequest.mPromise->MaybeRejectWithAbortError("The lock request is aborted");
105 } else {
106 JSContext* cx = jsapi.cx();
107 JS::Rooted<JS::Value> reason(cx);
108 Signal()->GetReason(cx, &reason);
109 mRequest.mPromise->MaybeReject(reason);
112 Unfollow();
113 Send__delete__(this, true);
116 inline LockManagerChild* LockRequestChild::CastedManager() const {
117 return static_cast<LockManagerChild*>(Manager());
120 } // namespace mozilla::dom::locks