tor-browser

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

LockManagerChild.cpp (3511B)


      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/. */
      6 
      7 #include "LockManagerChild.h"
      8 
      9 #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"
     16 
     17 namespace mozilla::dom::locks {
     18 
     19 LockManagerChild::LockManagerChild(nsIGlobalObject* aOwner) : mOwner(aOwner) {
     20  if (!NS_IsMainThread()) {
     21    mWorkerRef = IPCWorkerRef::Create(GetCurrentThreadWorkerPrivate(),
     22                                      "LockManagerChild");
     23  }
     24 }
     25 
     26 void LockManagerChild::NotifyBFCacheOnMainThread(nsPIDOMWindowInner* aInner,
     27                                                 bool aCreated) {
     28  AssertIsOnMainThread();
     29  if (!aInner) {
     30    return;
     31  }
     32  if (aCreated) {
     33    aInner->RemoveFromBFCacheSync();
     34  }
     35 
     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);
     45    }
     46  }
     47 }
     48 
     49 class BFCacheNotifyLockRunnable final : public WorkerProxyToMainThreadRunnable {
     50 public:
     51  explicit BFCacheNotifyLockRunnable(bool aCreated) : mCreated(aCreated) {}
     52 
     53  void RunOnMainThread(WorkerPrivate* aWorkerPrivate) override {
     54    MOZ_ASSERT(aWorkerPrivate);
     55    AssertIsOnMainThread();
     56    if (aWorkerPrivate->IsDedicatedWorker()) {
     57      LockManagerChild::NotifyBFCacheOnMainThread(
     58          aWorkerPrivate->GetAncestorWindow(), mCreated);
     59      return;
     60    }
     61    if (aWorkerPrivate->IsSharedWorker()) {
     62      aWorkerPrivate->GetRemoteWorkerController()->NotifyLock(mCreated);
     63      return;
     64    }
     65    MOZ_ASSERT_UNREACHABLE("Unexpected worker type");
     66  }
     67 
     68  void RunBackOnWorkerThreadForCleanup(WorkerPrivate* aWorkerPrivate) override {
     69    MOZ_ASSERT(aWorkerPrivate);
     70    aWorkerPrivate->AssertIsOnWorkerThread();
     71  }
     72 
     73 private:
     74  bool mCreated;
     75 };
     76 
     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));
     84  NotifyToWindow(true);
     85 }
     86 
     87 void LockManagerChild::NotifyRequestDestroy() const { NotifyToWindow(false); }
     88 
     89 void LockManagerChild::NotifyToWindow(bool aCreated) const {
     90  if (NS_IsMainThread()) {
     91    NotifyBFCacheOnMainThread(GetParentObject()->GetAsInnerWindow(), aCreated);
     92    return;
     93  }
     94 
     95  WorkerPrivate* wp = GetCurrentThreadWorkerPrivate();
     96  if (wp->IsDedicatedWorker() || wp->IsSharedWorker()) {
     97    RefPtr<BFCacheNotifyLockRunnable> runnable =
     98        new BFCacheNotifyLockRunnable(aCreated);
     99 
    100    runnable->Dispatch(wp);
    101  }
    102 };
    103 
    104 }  // namespace mozilla::dom::locks