Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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/. */
#ifndef mozilla_dom_SharedWorkerManager_h
#define mozilla_dom_SharedWorkerManager_h
#include "SharedWorkerParent.h"
#include "mozilla/dom/RemoteWorkerController.h"
#include "mozilla/dom/quota/CheckedUnsafePtr.h"
#include "nsISupportsImpl.h"
#include "nsTArray.h"
class nsIPrincipal;
namespace mozilla::dom {
class UniqueMessagePortId;
class RemoteWorkerData;
class SharedWorkerManager;
class SharedWorkerService;
// Main-thread only object that keeps a manager and the service alive.
// When the last SharedWorkerManagerHolder is released, the corresponding
// manager unregisters itself from the service and terminates the worker.
class SharedWorkerManagerHolder final
: public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
public:
NS_INLINE_DECL_REFCOUNTING(SharedWorkerManagerHolder);
SharedWorkerManagerHolder(SharedWorkerManager* aManager,
SharedWorkerService* aService);
SharedWorkerManager* Manager() const { return mManager; }
SharedWorkerService* Service() const { return mService; }
private:
~SharedWorkerManagerHolder();
const RefPtr<SharedWorkerManager> mManager;
const RefPtr<SharedWorkerService> mService;
};
// Thread-safe wrapper for SharedWorkerManagerHolder.
class SharedWorkerManagerWrapper final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerManagerWrapper);
explicit SharedWorkerManagerWrapper(
already_AddRefed<SharedWorkerManagerHolder> aHolder);
SharedWorkerManager* Manager() const { return mHolder->Manager(); }
private:
~SharedWorkerManagerWrapper();
RefPtr<SharedWorkerManagerHolder> mHolder;
};
/**
* PBackground instance that corresponds to a single logical Shared Worker that
* exists somewhere in the process tree. Referenced/owned by multiple
* SharedWorkerParent instances on the PBackground thread. Holds/owns a single
* RemoteWorkerController to interact with the actual shared worker thread,
* wherever it is located. Creates the RemoteWorkerController via
* RemoteWorkerController::Create which uses RemoteWorkerManager::Launch under
* the hood.
*/
class SharedWorkerManager final : public RemoteWorkerObserver {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerManager, override);
// Called on main-thread thread methods
static already_AddRefed<SharedWorkerManagerHolder> Create(
SharedWorkerService* aService, nsIEventTarget* aPBackgroundEventTarget,
const RemoteWorkerData& aData, nsIPrincipal* aLoadingPrincipal,
const OriginAttributes& aEffectiveStoragePrincipalAttrs);
// Returns a holder if this manager matches. The holder blocks the shutdown of
// the manager.
already_AddRefed<SharedWorkerManagerHolder> MatchOnMainThread(
SharedWorkerService* aService, const nsACString& aDomain,
nsIURI* aScriptURL, const nsAString& aName,
nsIPrincipal* aLoadingPrincipal,
const OriginAttributes& aEffectiveStoragePrincipalAttrs);
// RemoteWorkerObserver
void CreationFailed() override;
void CreationSucceeded() override;
void ErrorReceived(const ErrorValue& aValue) override;
void LockNotified(bool aCreated) final;
void WebTransportNotified(bool aCreated) final;
void Terminated() override;
// Called on PBackground thread methods
bool MaybeCreateRemoteWorker(const RemoteWorkerData& aData,
uint64_t aWindowID,
UniqueMessagePortId& aPortIdentifier,
base::ProcessId aProcessId);
void AddActor(SharedWorkerParent* aParent);
void RemoveActor(SharedWorkerParent* aParent);
void UpdateSuspend();
void UpdateFrozen();
bool IsSecureContext() const;
void Terminate();
// Called on main-thread only.
void RegisterHolder(SharedWorkerManagerHolder* aHolder);
void UnregisterHolder(SharedWorkerManagerHolder* aHolder);
private:
SharedWorkerManager(nsIEventTarget* aPBackgroundEventTarget,
const RemoteWorkerData& aData,
nsIPrincipal* aLoadingPrincipal,
const OriginAttributes& aEffectiveStoragePrincipalAttrs);
~SharedWorkerManager();
nsCOMPtr<nsIEventTarget> mPBackgroundEventTarget;
nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
const nsCString mDomain;
const OriginAttributes mEffectiveStoragePrincipalAttrs;
const nsCOMPtr<nsIURI> mResolvedScriptURL;
const nsString mName;
const bool mIsSecureContext;
bool mSuspended;
bool mFrozen;
uint32_t mLockCount = 0;
uint32_t mWebTransportCount = 0;
// Raw pointers because SharedWorkerParent unregisters itself in
// ActorDestroy().
nsTArray<CheckedUnsafePtr<SharedWorkerParent>> mActors;
RefPtr<RemoteWorkerController> mRemoteWorkerController;
// Main-thread only. Raw Pointers because holders keep the manager alive and
// they unregister themselves in their DTOR.
nsTArray<CheckedUnsafePtr<SharedWorkerManagerHolder>> mHolders;
};
} // namespace mozilla::dom
#endif // mozilla_dom_SharedWorkerManager_h