1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/cache/CacheChild.h"
#include "CacheWorkerRef.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/cache/Cache.h"
#include "mozilla/dom/cache/CacheOpChild.h"
namespace mozilla::dom::cache {
// Declared in ActorUtils.h
already_AddRefed<PCacheChild> AllocPCacheChild(ActorChild* aParentActor) {
return MakeAndAddRef<CacheChild>(aParentActor);
}
// Declared in ActorUtils.h
void DeallocPCacheChild(PCacheChild* aActor) { delete aActor; }
CacheChild::CacheChild(ActorChild* aParentActor)
: mParentActor(aParentActor),
mListener(nullptr),
mLocked(false),
mDelayedDestroy(false) {
MOZ_COUNT_CTOR(cache::CacheChild);
}
CacheChild::~CacheChild() {
MOZ_COUNT_DTOR(cache::CacheChild);
NS_ASSERT_OWNINGTHREAD(CacheChild);
MOZ_DIAGNOSTIC_ASSERT(!mListener);
MOZ_DIAGNOSTIC_ASSERT(!mLocked);
}
void CacheChild::SetListener(CacheChildListener* aListener) {
NS_ASSERT_OWNINGTHREAD(CacheChild);
MOZ_DIAGNOSTIC_ASSERT(!mListener);
mListener = aListener;
MOZ_DIAGNOSTIC_ASSERT(mListener);
}
void CacheChild::ClearListener() {
NS_ASSERT_OWNINGTHREAD(CacheChild);
MOZ_DIAGNOSTIC_ASSERT(mListener);
mListener = nullptr;
}
void CacheChild::StartDestroyFromListener() {
NS_ASSERT_OWNINGTHREAD(CacheChild);
// The listener should be held alive by any async operations, so if it
// is going away then there must not be any child actors. This in turn
// ensures that StartDestroy() will not trigger the delayed path.
MOZ_DIAGNOSTIC_ASSERT(NumChildActors() == 0);
StartDestroy();
}
void CacheChild::DestroyInternal() {
CacheChildListener* listener = mListener;
// StartDestroy() can get called from either Cache or the WorkerRef.
// Theoretically we can get double called if the right race happens. Handle
// that by just ignoring the second StartDestroy() call.
if (!listener) {
return;
}
listener->OnActorDestroy(this);
// Cache listener should call ClearListener() in OnActorDestroy()
MOZ_DIAGNOSTIC_ASSERT(!mListener);
// Start actor destruction from parent process
QM_WARNONLY_TRY(OkIf(SendTeardown()));
}
void CacheChild::StartDestroy() {
NS_ASSERT_OWNINGTHREAD(CacheChild);
if (NumChildActors() != 0 || mLocked) {
mDelayedDestroy = true;
return;
}
DestroyInternal();
}
void CacheChild::ActorDestroy(ActorDestroyReason aReason) {
NS_ASSERT_OWNINGTHREAD(CacheChild);
CacheChildListener* listener = mListener;
if (listener) {
listener->OnActorDestroy(this);
// Cache listener should call ClearListener() in OnActorDestroy()
MOZ_DIAGNOSTIC_ASSERT(!mListener);
}
if (mParentActor) {
mParentActor->NoteDeletedActor();
}
RemoveWorkerRef();
}
void CacheChild::NoteDeletedActor() {
// Check to see if DestroyInternal was delayed because there were still active
// CacheOpChilds when StartDestroy was called from WorkerRef notification. If
// the last CacheOpChild is getting destructed; it's the time for us to
// SendTearDown to the other side.
if (NumChildActors() == 0 && mDelayedDestroy && !mLocked) DestroyInternal();
}
already_AddRefed<PCacheOpChild> CacheChild::AllocPCacheOpChild(
const CacheOpArgs& aOpArgs) {
MOZ_CRASH("CacheOpChild should be manually constructed.");
return nullptr;
}
void CacheChild::Lock() {
NS_ASSERT_OWNINGTHREAD(CacheChild);
MOZ_DIAGNOSTIC_ASSERT(!mLocked);
mLocked = true;
}
void CacheChild::Unlock() {
NS_ASSERT_OWNINGTHREAD(CacheChild);
MOZ_DIAGNOSTIC_ASSERT(mLocked);
mLocked = false;
}
} // namespace mozilla::dom::cache
|