зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1559919 - Finish the WorkerHolder cleanup - part 11 - WorkerHolder replaced by WorkerRef, r=asuth
Differential Revision: https://phabricator.services.mozilla.com/D35230 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
46c41f3318
Коммит
2a3e21430e
|
@ -1,71 +0,0 @@
|
|||
/* -*- 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 "WorkerHolder.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
void AssertOnOwningThread(void* aThread) {
|
||||
if (MOZ_UNLIKELY(aThread != GetCurrentVirtualThread())) {
|
||||
MOZ_CRASH_UNSAFE("WorkerHolder on the wrong thread.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WorkerHolder::WorkerHolder(const char* aName, Behavior aBehavior)
|
||||
: mWorkerPrivate(nullptr),
|
||||
mBehavior(aBehavior),
|
||||
mThread(GetCurrentVirtualThread()),
|
||||
mName(aName) {}
|
||||
|
||||
WorkerHolder::~WorkerHolder() {
|
||||
AssertOnOwningThread(mThread);
|
||||
ReleaseWorkerInternal();
|
||||
MOZ_ASSERT(mWorkerPrivate == nullptr);
|
||||
}
|
||||
|
||||
bool WorkerHolder::HoldWorker(WorkerPrivate* aWorkerPrivate,
|
||||
WorkerStatus aFailStatus) {
|
||||
AssertOnOwningThread(mThread);
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aFailStatus >= Canceling);
|
||||
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
if (!aWorkerPrivate->AddHolder(this, aFailStatus)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mWorkerPrivate = aWorkerPrivate;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorkerHolder::ReleaseWorker() {
|
||||
AssertOnOwningThread(mThread);
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
|
||||
ReleaseWorkerInternal();
|
||||
}
|
||||
|
||||
WorkerHolder::Behavior WorkerHolder::GetBehavior() const { return mBehavior; }
|
||||
|
||||
void WorkerHolder::ReleaseWorkerInternal() {
|
||||
AssertOnOwningThread(mThread);
|
||||
|
||||
if (mWorkerPrivate) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
mWorkerPrivate->RemoveHolder(this);
|
||||
mWorkerPrivate = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -2047,7 +2047,7 @@ bool WorkerPrivate::PrincipalIsValid() const {
|
|||
|
||||
WorkerPrivate::WorkerThreadAccessible::WorkerThreadAccessible(
|
||||
WorkerPrivate* const aParent)
|
||||
: mNumHoldersPreventingShutdownStart(0),
|
||||
: mNumWorkerRefsPreventingShutdownStart(0),
|
||||
mDebuggerEventLoopLevel(0),
|
||||
mErrorHandlerRecursionCount(0),
|
||||
mNextTimeoutId(1),
|
||||
|
@ -2706,7 +2706,7 @@ void WorkerPrivate::DoRunLoop(JSContext* aCx) {
|
|||
while (mControlQueue.IsEmpty() &&
|
||||
!(debuggerRunnablesPending = !mDebuggerQueue.IsEmpty()) &&
|
||||
!(normalRunnablesPending = NS_HasPendingEvents(mThread)) &&
|
||||
!(mStatus != Running && !HasActiveHolders())) {
|
||||
!(mStatus != Running && !HasActiveWorkerRefs())) {
|
||||
WaitForWorkerEvents();
|
||||
}
|
||||
|
||||
|
@ -2724,7 +2724,7 @@ void WorkerPrivate::DoRunLoop(JSContext* aCx) {
|
|||
}
|
||||
|
||||
// if all holders are done then we can kill this thread.
|
||||
if (currentStatus != Running && !HasActiveHolders()) {
|
||||
if (currentStatus != Running && !HasActiveWorkerRefs()) {
|
||||
// Now we are ready to kill the worker thread.
|
||||
if (currentStatus == Canceling) {
|
||||
NotifyInternal(Killing);
|
||||
|
@ -3503,7 +3503,9 @@ void WorkerPrivate::RemoveChildWorker(WorkerPrivate* aChildWorker) {
|
|||
}
|
||||
}
|
||||
|
||||
bool WorkerPrivate::AddHolder(WorkerHolder* aHolder, WorkerStatus aFailStatus) {
|
||||
bool WorkerPrivate::AddWorkerRef(WorkerRef* aWorkerRef,
|
||||
WorkerStatus aFailStatus) {
|
||||
MOZ_ASSERT(aWorkerRef);
|
||||
MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data);
|
||||
|
||||
{
|
||||
|
@ -3514,46 +3516,46 @@ bool WorkerPrivate::AddHolder(WorkerHolder* aHolder, WorkerStatus aFailStatus) {
|
|||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!data->mHolders.Contains(aHolder), "Already know about this one!");
|
||||
MOZ_ASSERT(!data->mWorkerRefs.Contains(aWorkerRef),
|
||||
"Already know about this one!");
|
||||
|
||||
if (aHolder->GetBehavior() == WorkerHolder::PreventIdleShutdownStart) {
|
||||
if (!data->mNumHoldersPreventingShutdownStart &&
|
||||
if (aWorkerRef->IsPreventingShutdown()) {
|
||||
if (!data->mNumWorkerRefsPreventingShutdownStart &&
|
||||
!ModifyBusyCountFromWorker(true)) {
|
||||
return false;
|
||||
}
|
||||
data->mNumHoldersPreventingShutdownStart += 1;
|
||||
data->mNumWorkerRefsPreventingShutdownStart += 1;
|
||||
}
|
||||
|
||||
data->mHolders.AppendElement(aHolder);
|
||||
data->mWorkerRefs.AppendElement(aWorkerRef);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorkerPrivate::RemoveHolder(WorkerHolder* aHolder) {
|
||||
void WorkerPrivate::RemoveWorkerRef(WorkerRef* aWorkerRef) {
|
||||
MOZ_ASSERT(aWorkerRef);
|
||||
MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data);
|
||||
|
||||
MOZ_ASSERT(data->mHolders.Contains(aHolder), "Didn't know about this one!");
|
||||
data->mHolders.RemoveElement(aHolder);
|
||||
MOZ_ASSERT(data->mWorkerRefs.Contains(aWorkerRef),
|
||||
"Didn't know about this one!");
|
||||
data->mWorkerRefs.RemoveElement(aWorkerRef);
|
||||
|
||||
if (aHolder->GetBehavior() == WorkerHolder::PreventIdleShutdownStart) {
|
||||
data->mNumHoldersPreventingShutdownStart -= 1;
|
||||
if (!data->mNumHoldersPreventingShutdownStart &&
|
||||
if (aWorkerRef->IsPreventingShutdown()) {
|
||||
data->mNumWorkerRefsPreventingShutdownStart -= 1;
|
||||
if (!data->mNumWorkerRefsPreventingShutdownStart &&
|
||||
!ModifyBusyCountFromWorker(false)) {
|
||||
NS_WARNING("Failed to modify busy count!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorkerPrivate::NotifyHolders(WorkerStatus aStatus) {
|
||||
void WorkerPrivate::NotifyWorkerRefs(WorkerStatus aStatus) {
|
||||
MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data);
|
||||
|
||||
NS_ASSERTION(aStatus > Closing, "Bad status!");
|
||||
|
||||
nsTObserverArray<WorkerHolder*>::ForwardIterator iter(data->mHolders);
|
||||
nsTObserverArray<WorkerRef*>::ForwardIterator iter(data->mWorkerRefs);
|
||||
while (iter.HasMore()) {
|
||||
WorkerHolder* holder = iter.GetNext();
|
||||
if (!holder->Notify(aStatus)) {
|
||||
NS_WARNING("Failed to notify holder!");
|
||||
}
|
||||
iter.GetNext()->Notify();
|
||||
}
|
||||
|
||||
AutoTArray<WorkerPrivate*, 10> children;
|
||||
|
@ -4060,7 +4062,7 @@ bool WorkerPrivate::NotifyInternal(WorkerStatus aStatus) {
|
|||
|
||||
// Let all our holders know the new status.
|
||||
if (aStatus > Closing) {
|
||||
NotifyHolders(aStatus);
|
||||
NotifyWorkerRefs(aStatus);
|
||||
}
|
||||
|
||||
// If this is the first time our status has changed then we need to clear the
|
||||
|
@ -4801,11 +4803,13 @@ void WorkerPrivate::AssertIsOnWorkerThread() const {
|
|||
void WorkerPrivate::DumpCrashInformation(nsACString& aString) {
|
||||
MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data);
|
||||
|
||||
nsTObserverArray<WorkerHolder*>::ForwardIterator iter(data->mHolders);
|
||||
nsTObserverArray<WorkerRef*>::ForwardIterator iter(data->mWorkerRefs);
|
||||
while (iter.HasMore()) {
|
||||
WorkerHolder* holder = iter.GetNext();
|
||||
WorkerRef* workerRef = iter.GetNext();
|
||||
if (workerRef->IsPreventingShutdown()) {
|
||||
aString.Append("|");
|
||||
aString.Append(holder->Name());
|
||||
aString.Append(workerRef->Name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_dom_workers_workerprivate_h__
|
||||
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/dom/WorkerStatus.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
|
@ -20,7 +21,6 @@
|
|||
|
||||
#include "js/ContextOptions.h"
|
||||
#include "mozilla/dom/Worker.h"
|
||||
#include "mozilla/dom/WorkerHolder.h"
|
||||
#include "mozilla/dom/WorkerLoadInfo.h"
|
||||
#include "mozilla/dom/workerinternals/JSSettings.h"
|
||||
#include "mozilla/dom/workerinternals/Queue.h"
|
||||
|
@ -52,6 +52,7 @@ class WorkerDebuggerGlobalScope;
|
|||
class WorkerErrorReport;
|
||||
class WorkerEventTarget;
|
||||
class WorkerGlobalScope;
|
||||
class WorkerRef;
|
||||
class WorkerRunnable;
|
||||
class WorkerDebuggeeRunnable;
|
||||
class WorkerThread;
|
||||
|
@ -922,7 +923,7 @@ class WorkerPrivate : public RelativeTimeline {
|
|||
void WaitForWorkerEvents();
|
||||
|
||||
// If the worker shutdown status is equal or greater then aFailStatus, this
|
||||
// operation will fail and nullptr will be returned. See WorkerHolder.h for
|
||||
// operation will fail and nullptr will be returned. See WorkerStatus.h for
|
||||
// more information about the correct value to use.
|
||||
already_AddRefed<nsIEventTarget> CreateNewSyncLoop(WorkerStatus aFailStatus);
|
||||
|
||||
|
@ -938,16 +939,18 @@ class WorkerPrivate : public RelativeTimeline {
|
|||
|
||||
void ShutdownGCTimers();
|
||||
|
||||
bool AddHolder(WorkerHolder* aHolder, WorkerStatus aFailStatus);
|
||||
friend class WorkerRef;
|
||||
|
||||
void RemoveHolder(WorkerHolder* aHolder);
|
||||
bool AddWorkerRef(WorkerRef* aWorkerRefer, WorkerStatus aFailStatus);
|
||||
|
||||
void NotifyHolders(WorkerStatus aStatus);
|
||||
void RemoveWorkerRef(WorkerRef* aWorkerRef);
|
||||
|
||||
bool HasActiveHolders() {
|
||||
void NotifyWorkerRefs(WorkerStatus aStatus);
|
||||
|
||||
bool HasActiveWorkerRefs() {
|
||||
MOZ_ACCESS_THREAD_BOUND(mWorkerThreadAccessible, data);
|
||||
return !(data->mChildWorkers.IsEmpty() && data->mTimeouts.IsEmpty() &&
|
||||
data->mHolders.IsEmpty());
|
||||
data->mWorkerRefs.IsEmpty());
|
||||
}
|
||||
|
||||
// Internal logic to dispatch a runnable. This is separate from Dispatch()
|
||||
|
@ -965,7 +968,6 @@ class WorkerPrivate : public RelativeTimeline {
|
|||
|
||||
class EventTarget;
|
||||
friend class EventTarget;
|
||||
friend class mozilla::dom::WorkerHolder;
|
||||
friend class AutoSyncLoopHolder;
|
||||
|
||||
struct TimeoutInfo;
|
||||
|
@ -1084,7 +1086,7 @@ class WorkerPrivate : public RelativeTimeline {
|
|||
RefPtr<WorkerGlobalScope> mScope;
|
||||
RefPtr<WorkerDebuggerGlobalScope> mDebuggerScope;
|
||||
nsTArray<WorkerPrivate*> mChildWorkers;
|
||||
nsTObserverArray<WorkerHolder*> mHolders;
|
||||
nsTObserverArray<WorkerRef*> mWorkerRefs;
|
||||
nsTArray<nsAutoPtr<TimeoutInfo>> mTimeouts;
|
||||
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
@ -1096,7 +1098,7 @@ class WorkerPrivate : public RelativeTimeline {
|
|||
|
||||
UniquePtr<ClientSource> mClientSource;
|
||||
|
||||
uint32_t mNumHoldersPreventingShutdownStart;
|
||||
uint32_t mNumWorkerRefsPreventingShutdownStart;
|
||||
uint32_t mDebuggerEventLoopLevel;
|
||||
|
||||
uint32_t mErrorHandlerRecursionCount;
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "WorkerRef.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
#include "WorkerHolder.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
|
@ -43,46 +42,50 @@ class ReleaseRefControlRunnable final : public WorkerControlRunnable {
|
|||
|
||||
} // namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WorkerRef::Holder
|
||||
|
||||
class WorkerRef::Holder final : public mozilla::dom::WorkerHolder {
|
||||
public:
|
||||
Holder(const char* aName, WorkerRef* aWorkerRef, Behavior aBehavior)
|
||||
: mozilla::dom::WorkerHolder(aName, aBehavior), mWorkerRef(aWorkerRef) {}
|
||||
|
||||
bool Notify(WorkerStatus aStatus) override {
|
||||
MOZ_ASSERT(mWorkerRef);
|
||||
|
||||
if (aStatus < Canceling) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Let's keep this object alive for the whole Notify() execution.
|
||||
RefPtr<WorkerRef> workerRef;
|
||||
workerRef = mWorkerRef;
|
||||
|
||||
workerRef->Notify();
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
WorkerRef* mWorkerRef;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WorkerRef
|
||||
|
||||
WorkerRef::WorkerRef(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate) {
|
||||
WorkerRef::WorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||
bool aIsPreventingShutdown)
|
||||
: mWorkerPrivate(aWorkerPrivate),
|
||||
mName(aName),
|
||||
mIsPreventingShutdown(aIsPreventingShutdown),
|
||||
mHolding(false) {
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aName);
|
||||
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
}
|
||||
|
||||
WorkerRef::~WorkerRef() { NS_ASSERT_OWNINGTHREAD(WorkerRef); }
|
||||
WorkerRef::~WorkerRef() {
|
||||
NS_ASSERT_OWNINGTHREAD(WorkerRef);
|
||||
ReleaseWorker();
|
||||
}
|
||||
|
||||
void WorkerRef::ReleaseWorker() {
|
||||
if (mHolding) {
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
|
||||
mWorkerPrivate->RemoveWorkerRef(this);
|
||||
mWorkerPrivate = nullptr;
|
||||
|
||||
mHolding = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WorkerRef::HoldWorker(WorkerStatus aStatus) {
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
MOZ_ASSERT(!mHolding);
|
||||
|
||||
if (NS_WARN_IF(!mWorkerPrivate->AddWorkerRef(this, aStatus))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mHolding = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorkerRef::Notify() {
|
||||
MOZ_ASSERT(mHolder);
|
||||
NS_ASSERT_OWNINGTHREAD(WorkerRef);
|
||||
|
||||
if (!mCallback) {
|
||||
|
@ -105,30 +108,30 @@ already_AddRefed<WeakWorkerRef> WeakWorkerRef::Create(
|
|||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
RefPtr<WeakWorkerRef> ref = new WeakWorkerRef(aWorkerPrivate);
|
||||
|
||||
// This holder doesn't keep the worker alive.
|
||||
UniquePtr<Holder> holder(new Holder("WeakWorkerRef::Holder", ref,
|
||||
WorkerHolder::AllowIdleShutdownStart));
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
|
||||
if (!ref->HoldWorker(Canceling)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ref->mHolder = std::move(holder);
|
||||
ref->mCallback = std::move(aCallback);
|
||||
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
WeakWorkerRef::WeakWorkerRef(WorkerPrivate* aWorkerPrivate)
|
||||
: WorkerRef(aWorkerPrivate) {}
|
||||
: WorkerRef(aWorkerPrivate, "WeakWorkerRef", false) {}
|
||||
|
||||
WeakWorkerRef::~WeakWorkerRef() = default;
|
||||
|
||||
void WeakWorkerRef::Notify() {
|
||||
WorkerRef::Notify();
|
||||
MOZ_ASSERT(mHolding);
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
|
||||
mHolder = nullptr;
|
||||
mWorkerPrivate = nullptr;
|
||||
// Notify could drop the last reference to this object. We must keep it alive
|
||||
// in order to call ReleaseWorker() immediately after.
|
||||
RefPtr<WeakWorkerRef> kungFuGrip = this;
|
||||
|
||||
WorkerRef::Notify();
|
||||
ReleaseWorker();
|
||||
}
|
||||
|
||||
WorkerPrivate* WeakWorkerRef::GetPrivate() const {
|
||||
|
@ -168,27 +171,21 @@ already_AddRefed<StrongWorkerRef> StrongWorkerRef::CreateImpl(
|
|||
MOZ_ASSERT(aWorkerPrivate);
|
||||
MOZ_ASSERT(aName);
|
||||
|
||||
RefPtr<StrongWorkerRef> ref = new StrongWorkerRef(aWorkerPrivate);
|
||||
|
||||
// The worker is kept alive by this holder.
|
||||
UniquePtr<Holder> holder(
|
||||
new Holder(aName, ref, WorkerHolder::PreventIdleShutdownStart));
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, aFailStatus))) {
|
||||
RefPtr<StrongWorkerRef> ref = new StrongWorkerRef(aWorkerPrivate, aName);
|
||||
if (!ref->HoldWorker(aFailStatus)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ref->mHolder = std::move(holder);
|
||||
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
StrongWorkerRef::StrongWorkerRef(WorkerPrivate* aWorkerPrivate)
|
||||
: WorkerRef(aWorkerPrivate) {}
|
||||
StrongWorkerRef::StrongWorkerRef(WorkerPrivate* aWorkerPrivate,
|
||||
const char* aName)
|
||||
: WorkerRef(aWorkerPrivate, aName, true) {}
|
||||
|
||||
StrongWorkerRef::~StrongWorkerRef() { NS_ASSERT_OWNINGTHREAD(StrongWorkerRef); }
|
||||
StrongWorkerRef::~StrongWorkerRef() = default;
|
||||
|
||||
WorkerPrivate* StrongWorkerRef::Private() const {
|
||||
MOZ_ASSERT(mHolder);
|
||||
NS_ASSERT_OWNINGTHREAD(StrongWorkerRef);
|
||||
return mWorkerPrivate;
|
||||
}
|
||||
|
@ -226,28 +223,22 @@ already_AddRefed<IPCWorkerRef> IPCWorkerRef::Create(
|
|||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
RefPtr<IPCWorkerRef> ref = new IPCWorkerRef(aWorkerPrivate);
|
||||
|
||||
// This holder doesn't keep the worker alive.
|
||||
UniquePtr<Holder> holder(
|
||||
new Holder(aName, ref, WorkerHolder::AllowIdleShutdownStart));
|
||||
if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
|
||||
RefPtr<IPCWorkerRef> ref = new IPCWorkerRef(aWorkerPrivate, aName);
|
||||
if (!ref->HoldWorker(Canceling)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ref->mHolder = std::move(holder);
|
||||
ref->mCallback = std::move(aCallback);
|
||||
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
IPCWorkerRef::IPCWorkerRef(WorkerPrivate* aWorkerPrivate)
|
||||
: WorkerRef(aWorkerPrivate) {}
|
||||
IPCWorkerRef::IPCWorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName)
|
||||
: WorkerRef(aWorkerPrivate, aName, false) {}
|
||||
|
||||
IPCWorkerRef::~IPCWorkerRef() = default;
|
||||
|
||||
WorkerPrivate* IPCWorkerRef::Private() const {
|
||||
MOZ_ASSERT(mHolder);
|
||||
NS_ASSERT_OWNINGTHREAD(IPCWorkerRef);
|
||||
return mWorkerPrivate;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define mozilla_dom_workers_WorkerRef_h
|
||||
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/dom/WorkerHolder.h"
|
||||
#include "mozilla/dom/WorkerStatus.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include <functional>
|
||||
|
||||
|
@ -30,7 +30,7 @@ namespace dom {
|
|||
* d. Firefox is shutting down.
|
||||
*
|
||||
* When a DOM Worker goes away, it does several steps. See more in
|
||||
* WorkerHolder.h. The DOM Worker thread will basically stop scheduling
|
||||
* WorkerStatus.h. The DOM Worker thread will basically stop scheduling
|
||||
* WorkerRunnables, and eventually WorkerControlRunnables. But if there is
|
||||
* something preventing the shutting down, it will always possible to dispatch
|
||||
* WorkerControlRunnables. Of course, at some point, the worker _must_ be
|
||||
|
@ -103,22 +103,33 @@ class StrongWorkerRef;
|
|||
class ThreadSafeWorkerRef;
|
||||
|
||||
class WorkerRef {
|
||||
friend class WorkerPrivate;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(WorkerRef)
|
||||
|
||||
protected:
|
||||
class Holder;
|
||||
friend class Holder;
|
||||
|
||||
explicit WorkerRef(WorkerPrivate* aWorkerPrivate);
|
||||
WorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||
bool aIsPreventingShutdown);
|
||||
virtual ~WorkerRef();
|
||||
|
||||
virtual void Notify();
|
||||
|
||||
bool HoldWorker(WorkerStatus aStatus);
|
||||
void ReleaseWorker();
|
||||
|
||||
bool IsPreventingShutdown() const { return mIsPreventingShutdown; }
|
||||
|
||||
const char* Name() const { return mName; }
|
||||
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
UniquePtr<WorkerHolder> mHolder;
|
||||
|
||||
std::function<void()> mCallback;
|
||||
const char* const mName;
|
||||
const bool mIsPreventingShutdown;
|
||||
|
||||
// True if this WorkerRef has been added to a WorkerPrivate.
|
||||
bool mHolding;
|
||||
};
|
||||
|
||||
class WeakWorkerRef final : public WorkerRef {
|
||||
|
@ -171,7 +182,7 @@ class StrongWorkerRef final : public WorkerRef {
|
|||
WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||
WorkerStatus aFailStatus);
|
||||
|
||||
explicit StrongWorkerRef(WorkerPrivate* aWorkerPrivate);
|
||||
StrongWorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName);
|
||||
~StrongWorkerRef();
|
||||
};
|
||||
|
||||
|
@ -200,7 +211,7 @@ class IPCWorkerRef final : public WorkerRef {
|
|||
WorkerPrivate* Private() const;
|
||||
|
||||
private:
|
||||
explicit IPCWorkerRef(WorkerPrivate* aWorkerPrivate);
|
||||
IPCWorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName);
|
||||
~IPCWorkerRef();
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
#include "mozilla/dom/WorkerStatus.h"
|
||||
|
||||
#include "nsICancelableRunnable.h"
|
||||
|
||||
|
|
|
@ -4,16 +4,12 @@
|
|||
* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_workers_WorkerHolder_h
|
||||
#define mozilla_dom_workers_WorkerHolder_h
|
||||
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#ifndef mozilla_dom_workers_WorkerStatus_h
|
||||
#define mozilla_dom_workers_WorkerStatus_h
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class WorkerPrivate;
|
||||
|
||||
/**
|
||||
* Use this chart to help figure out behavior during each of the closing
|
||||
* statuses. Details below.
|
||||
|
@ -40,9 +36,9 @@ enum WorkerStatus {
|
|||
|
||||
// Inner script called close() on the worker global scope. Setting this
|
||||
// status causes the worker to clear its queue of events but does not abort
|
||||
// the currently running script. WorkerHolder/WorkerRef objects are not going
|
||||
// to be notified because the behavior of APIs/Components should not change
|
||||
// during this status yet.
|
||||
// the currently running script. WorkerRef objects are not going to be
|
||||
// notified because the behavior of APIs/Components should not change during
|
||||
// this status yet.
|
||||
Closing,
|
||||
|
||||
// Either the user navigated away from the owning page or the owning page fell
|
||||
|
@ -58,42 +54,7 @@ enum WorkerStatus {
|
|||
Dead
|
||||
};
|
||||
|
||||
class WorkerHolder {
|
||||
public:
|
||||
enum Behavior {
|
||||
AllowIdleShutdownStart,
|
||||
PreventIdleShutdownStart,
|
||||
};
|
||||
|
||||
explicit WorkerHolder(const char* aName,
|
||||
Behavior aBehavior = PreventIdleShutdownStart);
|
||||
virtual ~WorkerHolder();
|
||||
|
||||
bool HoldWorker(WorkerPrivate* aWorkerPrivate, WorkerStatus aFailStatus);
|
||||
void ReleaseWorker();
|
||||
|
||||
virtual bool Notify(WorkerStatus aStatus) = 0;
|
||||
|
||||
Behavior GetBehavior() const;
|
||||
|
||||
const char* Name() const { return mName; }
|
||||
|
||||
protected:
|
||||
void ReleaseWorkerInternal();
|
||||
|
||||
WorkerPrivate* MOZ_NON_OWNING_REF mWorkerPrivate;
|
||||
|
||||
private:
|
||||
void AssertIsOwningThread() const;
|
||||
|
||||
const Behavior mBehavior;
|
||||
|
||||
// For debugging only.
|
||||
void* mThread;
|
||||
const char* mName;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_dom_workers_WorkerHolder_h */
|
||||
#endif /* mozilla_dom_workers_WorkerStatus_h */
|
|
@ -17,7 +17,6 @@ EXPORTS.mozilla.dom += [
|
|||
'WorkerDebugger.h',
|
||||
'WorkerDebuggerManager.h',
|
||||
'WorkerError.h',
|
||||
'WorkerHolder.h',
|
||||
'WorkerLoadInfo.h',
|
||||
'WorkerLocation.h',
|
||||
'WorkerNavigator.h',
|
||||
|
@ -25,6 +24,7 @@ EXPORTS.mozilla.dom += [
|
|||
'WorkerRef.h',
|
||||
'WorkerRunnable.h',
|
||||
'WorkerScope.h',
|
||||
'WorkerStatus.h',
|
||||
]
|
||||
|
||||
# Private stuff.
|
||||
|
@ -56,7 +56,6 @@ UNIFIED_SOURCES += [
|
|||
'WorkerDebuggerManager.cpp',
|
||||
'WorkerError.cpp',
|
||||
'WorkerEventTarget.cpp',
|
||||
'WorkerHolder.cpp',
|
||||
'WorkerLoadInfo.cpp',
|
||||
'WorkerLocation.cpp',
|
||||
'WorkerNavigator.cpp',
|
||||
|
|
Загрузка…
Ссылка в новой задаче