diff options
Diffstat (limited to 'dom/cache/CacheWorkerHolder.cpp')
-rw-r--r-- | dom/cache/CacheWorkerHolder.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/dom/cache/CacheWorkerHolder.cpp b/dom/cache/CacheWorkerHolder.cpp new file mode 100644 index 000000000..3879e1521 --- /dev/null +++ b/dom/cache/CacheWorkerHolder.cpp @@ -0,0 +1,109 @@ +/* -*- 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/CacheWorkerHolder.h" + +#include "mozilla/dom/cache/ActorChild.h" +#include "WorkerPrivate.h" + +namespace mozilla { +namespace dom { +namespace cache { + +using mozilla::dom::workers::Terminating; +using mozilla::dom::workers::Status; +using mozilla::dom::workers::WorkerPrivate; + +// static +already_AddRefed<CacheWorkerHolder> +CacheWorkerHolder::Create(WorkerPrivate* aWorkerPrivate) +{ + MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate); + + RefPtr<CacheWorkerHolder> workerHolder = new CacheWorkerHolder(); + if (NS_WARN_IF(!workerHolder->HoldWorker(aWorkerPrivate, Terminating))) { + return nullptr; + } + + return workerHolder.forget(); +} + +void +CacheWorkerHolder::AddActor(ActorChild* aActor) +{ + NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder); + MOZ_DIAGNOSTIC_ASSERT(aActor); + MOZ_ASSERT(!mActorList.Contains(aActor)); + + mActorList.AppendElement(aActor); + + // Allow an actor to be added after we've entered the Notifying case. We + // can't stop the actor creation from racing with out destruction of the + // other actors and we need to wait for this extra one to close as well. + // Signal it should destroy itself right away. + if (mNotified) { + aActor->StartDestroy(); + } +} + +void +CacheWorkerHolder::RemoveActor(ActorChild* aActor) +{ + NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder); + MOZ_DIAGNOSTIC_ASSERT(aActor); + +#if defined(RELEASE_OR_BETA) + mActorList.RemoveElement(aActor); +#else + MOZ_DIAGNOSTIC_ASSERT(mActorList.RemoveElement(aActor)); +#endif + + MOZ_ASSERT(!mActorList.Contains(aActor)); +} + +bool +CacheWorkerHolder::Notified() const +{ + return mNotified; +} + +bool +CacheWorkerHolder::Notify(Status aStatus) +{ + NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder); + + // When the service worker thread is stopped we will get Terminating, + // but nothing higher than that. We must shut things down at Terminating. + if (aStatus < Terminating || mNotified) { + return true; + } + + mNotified = true; + + // Start the asynchronous destruction of our actors. These will call back + // into RemoveActor() once the actor is destroyed. + for (uint32_t i = 0; i < mActorList.Length(); ++i) { + MOZ_DIAGNOSTIC_ASSERT(mActorList[i]); + mActorList[i]->StartDestroy(); + } + + return true; +} + +CacheWorkerHolder::CacheWorkerHolder() + : mNotified(false) +{ +} + +CacheWorkerHolder::~CacheWorkerHolder() +{ + NS_ASSERT_OWNINGTHREAD(CacheWorkerHolder); + MOZ_DIAGNOSTIC_ASSERT(mActorList.IsEmpty()); +} + +} // namespace cache +} // namespace dom +} // namespace mozilla |