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/Document.h"
11 #include "mozilla/dom/RemoteWorkerChild.h"
12 #include "mozilla/dom/WindowGlobalChild.h"
13 #include "mozilla/dom/WorkerCommon.h"
14 #include "mozilla/dom/WorkerPrivate.h"
15 #include "mozilla/dom/WorkerRunnable.h"
17 namespace mozilla::dom::locks
{
19 LockManagerChild::LockManagerChild(nsIGlobalObject
* aOwner
) : mOwner(aOwner
) {
20 if (!NS_IsMainThread()) {
21 mWorkerRef
= IPCWorkerRef::Create(GetCurrentThreadWorkerPrivate(),
26 void LockManagerChild::NotifyBFCacheOnMainThread(nsPIDOMWindowInner
* aInner
,
28 AssertIsOnMainThread();
33 aInner
->RemoveFromBFCacheSync();
36 uint32_t count
= aInner
->UpdateLockCount(aCreated
);
37 // It's okay for WindowGlobalChild to not exist, as it should mean it already
38 // is destroyed and can't enter bfcache anyway.
39 if (WindowGlobalChild
* child
= aInner
->GetWindowGlobalChild()) {
40 if (aCreated
&& count
== 1) {
41 // The first lock is active.
42 child
->BlockBFCacheFor(BFCacheStatus::ACTIVE_LOCK
);
43 } else if (count
== 0) {
44 child
->UnblockBFCacheFor(BFCacheStatus::ACTIVE_LOCK
);
49 class BFCacheNotifyLockRunnable final
: public WorkerProxyToMainThreadRunnable
{
51 explicit BFCacheNotifyLockRunnable(bool aCreated
) : mCreated(aCreated
) {}
53 void RunOnMainThread(WorkerPrivate
* aWorkerPrivate
) override
{
54 MOZ_ASSERT(aWorkerPrivate
);
55 AssertIsOnMainThread();
56 if (aWorkerPrivate
->IsDedicatedWorker()) {
57 LockManagerChild::NotifyBFCacheOnMainThread(
58 aWorkerPrivate
->GetAncestorWindow(), mCreated
);
61 if (aWorkerPrivate
->IsSharedWorker()) {
62 aWorkerPrivate
->GetRemoteWorkerController()->NotifyLock(mCreated
);
65 MOZ_ASSERT_UNREACHABLE("Unexpected worker type");
68 void RunBackOnWorkerThreadForCleanup(WorkerPrivate
* aWorkerPrivate
) override
{
69 MOZ_ASSERT(aWorkerPrivate
);
70 aWorkerPrivate
->AssertIsOnWorkerThread();
77 void LockManagerChild::RequestLock(const LockRequest
& aRequest
,
78 const LockOptions
& aOptions
) {
79 auto requestActor
= MakeRefPtr
<LockRequestChild
>(aRequest
, aOptions
.mSignal
);
80 requestActor
->MaybeSetWorkerRef();
81 SendPLockRequestConstructor(
82 requestActor
, IPCLockRequest(nsString(aRequest
.mName
), aOptions
.mMode
,
83 aOptions
.mIfAvailable
, aOptions
.mSteal
));
87 void LockManagerChild::NotifyRequestDestroy() const { NotifyToWindow(false); }
89 void LockManagerChild::NotifyToWindow(bool aCreated
) const {
90 if (NS_IsMainThread()) {
91 NotifyBFCacheOnMainThread(GetParentObject()->GetAsInnerWindow(), aCreated
);
95 WorkerPrivate
* wp
= GetCurrentThreadWorkerPrivate();
96 if (wp
->IsDedicatedWorker() || wp
->IsSharedWorker()) {
97 RefPtr
<BFCacheNotifyLockRunnable
> runnable
=
98 new BFCacheNotifyLockRunnable(aCreated
);
100 runnable
->Dispatch(wp
);
104 } // namespace mozilla::dom::locks