зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central a=merge
This commit is contained in:
Коммит
30ead7d1ae
|
@ -0,0 +1,99 @@
|
||||||
|
/* -*- 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 "ClientHandle.h"
|
||||||
|
|
||||||
|
#include "ClientHandleChild.h"
|
||||||
|
#include "ClientHandleOpChild.h"
|
||||||
|
#include "ClientManager.h"
|
||||||
|
#include "mozilla/dom/PClientManagerChild.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
ClientHandle::~ClientHandle()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientHandle::Shutdown()
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientSource);
|
||||||
|
if (IsShutdown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShutdownThing();
|
||||||
|
|
||||||
|
mManager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<ClientOpPromise>
|
||||||
|
ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs)
|
||||||
|
{
|
||||||
|
RefPtr<ClientOpPromise::Private> promise =
|
||||||
|
new ClientOpPromise::Private(__func__);
|
||||||
|
|
||||||
|
// Hold a ref to the client until the remote operation completes. Otherwise
|
||||||
|
// the ClientHandle might get de-refed and teardown the actor before we
|
||||||
|
// get an answer.
|
||||||
|
RefPtr<ClientHandle> kungFuGrip = this;
|
||||||
|
promise->Then(mSerialEventTarget, __func__,
|
||||||
|
[kungFuGrip] (const ClientOpResult &) { },
|
||||||
|
[kungFuGrip] (nsresult) { });
|
||||||
|
|
||||||
|
MaybeExecute([aArgs, promise] (ClientHandleChild* aActor) {
|
||||||
|
ClientHandleOpChild* actor = new ClientHandleOpChild(aArgs, promise);
|
||||||
|
if (!aActor->SendPClientHandleOpConstructor(actor, aArgs)) {
|
||||||
|
// Constructor failure will reject promise via ActorDestroy()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
RefPtr<ClientOpPromise> ref = promise.get();
|
||||||
|
return ref.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientHandle::ClientHandle(ClientManager* aManager,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget,
|
||||||
|
const ClientInfo& aClientInfo)
|
||||||
|
: mManager(aManager)
|
||||||
|
, mSerialEventTarget(aSerialEventTarget)
|
||||||
|
, mClientInfo(aClientInfo)
|
||||||
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mManager);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mSerialEventTarget);
|
||||||
|
MOZ_ASSERT(mSerialEventTarget->IsOnCurrentThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientHandle::Activate(PClientManagerChild* aActor)
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientHandle);
|
||||||
|
|
||||||
|
if (IsShutdown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PClientHandleChild* actor =
|
||||||
|
aActor->SendPClientHandleConstructor(mClientInfo.ToIPC());
|
||||||
|
if (!actor) {
|
||||||
|
Shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivateThing(static_cast<ClientHandleChild*>(actor));
|
||||||
|
}
|
||||||
|
|
||||||
|
const ClientInfo&
|
||||||
|
ClientHandle::Info() const
|
||||||
|
{
|
||||||
|
return mClientInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* -*- 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_ClientHandle_h
|
||||||
|
#define _mozilla_dom_ClientHandle_h
|
||||||
|
|
||||||
|
#include "mozilla/dom/ClientInfo.h"
|
||||||
|
#include "mozilla/dom/ClientOpPromise.h"
|
||||||
|
#include "mozilla/dom/ClientThing.h"
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
#undef PostMessage
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class ClientManager;
|
||||||
|
class ClientHandleChild;
|
||||||
|
class ClientOpConstructorArgs;
|
||||||
|
class PClientManagerChild;
|
||||||
|
|
||||||
|
// The ClientHandle allows code to take a simple ClientInfo struct and
|
||||||
|
// convert it into a live actor-backed object attached to a particular
|
||||||
|
// ClientSource somewhere in the browser. If the ClientSource is
|
||||||
|
// destroyed then the ClientHandle will simply begin to reject operations.
|
||||||
|
// We do not currently provide a way to be notified when the ClientSource
|
||||||
|
// is destroyed, but this could be added in the future.
|
||||||
|
class ClientHandle final : public ClientThing<ClientHandleChild>
|
||||||
|
{
|
||||||
|
friend class ClientManager;
|
||||||
|
|
||||||
|
RefPtr<ClientManager> mManager;
|
||||||
|
nsCOMPtr<nsISerialEventTarget> mSerialEventTarget;
|
||||||
|
ClientInfo mClientInfo;
|
||||||
|
|
||||||
|
~ClientHandle();
|
||||||
|
|
||||||
|
void
|
||||||
|
Shutdown();
|
||||||
|
|
||||||
|
already_AddRefed<ClientOpPromise>
|
||||||
|
StartOp(const ClientOpConstructorArgs& aArgs);
|
||||||
|
|
||||||
|
// Private methods called by ClientManager
|
||||||
|
ClientHandle(ClientManager* aManager,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget,
|
||||||
|
const ClientInfo& aClientInfo);
|
||||||
|
|
||||||
|
void
|
||||||
|
Activate(PClientManagerChild* aActor);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const ClientInfo&
|
||||||
|
Info() const;
|
||||||
|
|
||||||
|
NS_INLINE_DECL_REFCOUNTING(ClientHandle);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // _mozilla_dom_ClientHandle_h
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ClientHandleParent.h"
|
#include "ClientHandleParent.h"
|
||||||
|
|
||||||
#include "ClientHandleOpParent.h"
|
#include "ClientHandleOpParent.h"
|
||||||
|
#include "ClientManagerService.h"
|
||||||
#include "ClientSourceParent.h"
|
#include "ClientSourceParent.h"
|
||||||
#include "mozilla/dom/ClientIPCTypes.h"
|
#include "mozilla/dom/ClientIPCTypes.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
@ -26,6 +27,10 @@ ClientHandleParent::RecvTeardown()
|
||||||
void
|
void
|
||||||
ClientHandleParent::ActorDestroy(ActorDestroyReason aReason)
|
ClientHandleParent::ActorDestroy(ActorDestroyReason aReason)
|
||||||
{
|
{
|
||||||
|
if (mSource) {
|
||||||
|
mSource->DetachHandle(this);
|
||||||
|
mSource = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PClientHandleOpParent*
|
PClientHandleOpParent*
|
||||||
|
@ -51,16 +56,32 @@ ClientHandleParent::RecvPClientHandleOpConstructor(PClientHandleOpParent* aActor
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientHandleParent::ClientHandleParent()
|
ClientHandleParent::ClientHandleParent()
|
||||||
|
: mService(ClientManagerService::GetOrCreateInstance())
|
||||||
|
, mSource(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientHandleParent::~ClientHandleParent()
|
ClientHandleParent::~ClientHandleParent()
|
||||||
{
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(!mSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientHandleParent::Init(const IPCClientInfo& aClientInfo)
|
ClientHandleParent::Init(const IPCClientInfo& aClientInfo)
|
||||||
{
|
{
|
||||||
|
mSource = mService->FindSource(aClientInfo.id(), aClientInfo.principalInfo());
|
||||||
|
if (!mSource) {
|
||||||
|
Unused << Send__delete__(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSource->AttachHandle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSourceParent*
|
||||||
|
ClientHandleParent::GetSource() const
|
||||||
|
{
|
||||||
|
return mSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -11,8 +11,14 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class ClientManagerService;
|
||||||
|
class ClientSourceParent;
|
||||||
|
|
||||||
class ClientHandleParent final : public PClientHandleParent
|
class ClientHandleParent final : public PClientHandleParent
|
||||||
{
|
{
|
||||||
|
RefPtr<ClientManagerService> mService;
|
||||||
|
ClientSourceParent* mSource;
|
||||||
|
|
||||||
// PClientHandleParent interface
|
// PClientHandleParent interface
|
||||||
mozilla::ipc::IPCResult
|
mozilla::ipc::IPCResult
|
||||||
RecvTeardown() override;
|
RecvTeardown() override;
|
||||||
|
@ -36,6 +42,9 @@ public:
|
||||||
|
|
||||||
void
|
void
|
||||||
Init(const IPCClientInfo& aClientInfo);
|
Init(const IPCClientInfo& aClientInfo);
|
||||||
|
|
||||||
|
ClientSourceParent*
|
||||||
|
GetSource() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -17,6 +17,10 @@ namespace dom {
|
||||||
|
|
||||||
struct ClientSourceConstructorArgs
|
struct ClientSourceConstructorArgs
|
||||||
{
|
{
|
||||||
|
nsID id;
|
||||||
|
ClientType type;
|
||||||
|
PrincipalInfo principalInfo;
|
||||||
|
TimeStamp creationTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IPCClientInfo
|
struct IPCClientInfo
|
||||||
|
|
|
@ -0,0 +1,236 @@
|
||||||
|
/* -*- 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 "ClientManager.h"
|
||||||
|
|
||||||
|
#include "ClientHandle.h"
|
||||||
|
#include "ClientManagerChild.h"
|
||||||
|
#include "ClientManagerOpChild.h"
|
||||||
|
#include "ClientSource.h"
|
||||||
|
#include "mozilla/dom/WorkerPrivate.h"
|
||||||
|
#include "mozilla/dom/workers/bindings/WorkerHolderToken.h"
|
||||||
|
#include "mozilla/ipc/BackgroundChild.h"
|
||||||
|
#include "mozilla/ipc/PBackgroundChild.h"
|
||||||
|
#include "prthread.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
using mozilla::ipc::BackgroundChild;
|
||||||
|
using mozilla::ipc::PBackgroundChild;
|
||||||
|
using mozilla::ipc::PrincipalInfo;
|
||||||
|
using mozilla::dom::workers::Closing;
|
||||||
|
using mozilla::dom::workers::GetCurrentThreadWorkerPrivate;
|
||||||
|
using mozilla::dom::workers::WorkerHolderToken;
|
||||||
|
using mozilla::dom::workers::WorkerPrivate;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
uint32_t kBadThreadLocalIndex = -1;
|
||||||
|
uint32_t sClientManagerThreadLocalIndex = kBadThreadLocalIndex;
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
ClientManager::ClientManager()
|
||||||
|
{
|
||||||
|
PBackgroundChild* parentActor = BackgroundChild::GetOrCreateForCurrentThread();
|
||||||
|
if (NS_WARN_IF(!parentActor)) {
|
||||||
|
Shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<WorkerHolderToken> workerHolderToken;
|
||||||
|
if (!NS_IsMainThread()) {
|
||||||
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
|
||||||
|
|
||||||
|
workerHolderToken =
|
||||||
|
WorkerHolderToken::Create(workerPrivate, Closing,
|
||||||
|
WorkerHolderToken::AllowIdleShutdownStart);
|
||||||
|
if (NS_WARN_IF(!workerHolderToken)) {
|
||||||
|
Shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientManagerChild* actor = new ClientManagerChild(workerHolderToken);
|
||||||
|
PClientManagerChild *sentActor =
|
||||||
|
parentActor->SendPClientManagerConstructor(actor);
|
||||||
|
if (NS_WARN_IF(!sentActor)) {
|
||||||
|
Shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(sentActor == actor);
|
||||||
|
|
||||||
|
ActivateThing(actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientManager::~ClientManager()
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientManager);
|
||||||
|
|
||||||
|
Shutdown();
|
||||||
|
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(this == PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
|
||||||
|
PRStatus status =
|
||||||
|
PR_SetThreadPrivate(sClientManagerThreadLocalIndex, nullptr);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientManager::Shutdown()
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientManager);
|
||||||
|
|
||||||
|
if (IsShutdown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShutdownThing();
|
||||||
|
}
|
||||||
|
|
||||||
|
UniquePtr<ClientSource>
|
||||||
|
ClientManager::CreateSourceInternal(ClientType aType,
|
||||||
|
const PrincipalInfo& aPrincipal)
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientManager);
|
||||||
|
|
||||||
|
if (IsShutdown()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsID id;
|
||||||
|
nsresult rv = nsContentUtils::GenerateUUIDInPlace(id);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSourceConstructorArgs args(id, aType, aPrincipal, TimeStamp::Now());
|
||||||
|
UniquePtr<ClientSource> source(new ClientSource(this, args));
|
||||||
|
source->Activate(GetActor());
|
||||||
|
|
||||||
|
return Move(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<ClientHandle>
|
||||||
|
ClientManager::CreateHandleInternal(const ClientInfo& aClientInfo,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget)
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientManager);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aSerialEventTarget);
|
||||||
|
|
||||||
|
if (IsShutdown()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<ClientHandle> handle = new ClientHandle(this, aSerialEventTarget,
|
||||||
|
aClientInfo);
|
||||||
|
handle->Activate(GetActor());
|
||||||
|
|
||||||
|
return handle.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<ClientOpPromise>
|
||||||
|
ClientManager::StartOp(const ClientOpConstructorArgs& aArgs,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget)
|
||||||
|
{
|
||||||
|
RefPtr<ClientOpPromise::Private> promise =
|
||||||
|
new ClientOpPromise::Private(__func__);
|
||||||
|
|
||||||
|
// Hold a ref to the client until the remote operation completes. Otherwise
|
||||||
|
// the ClientHandle might get de-refed and teardown the actor before we
|
||||||
|
// get an answer.
|
||||||
|
RefPtr<ClientManager> kungFuGrip = this;
|
||||||
|
promise->Then(aSerialEventTarget, __func__,
|
||||||
|
[kungFuGrip] (const ClientOpResult&) { },
|
||||||
|
[kungFuGrip] (nsresult) { });
|
||||||
|
|
||||||
|
MaybeExecute([aArgs, promise] (ClientManagerChild* aActor) {
|
||||||
|
ClientManagerOpChild* actor = new ClientManagerOpChild(aArgs, promise);
|
||||||
|
if (!aActor->SendPClientManagerOpConstructor(actor, aArgs)) {
|
||||||
|
// Constructor failure will reject promise via ActorDestroy()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
RefPtr<ClientOpPromise> ref = promise.get();
|
||||||
|
return ref.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<ClientManager>
|
||||||
|
ClientManager::GetOrCreateForCurrentThread()
|
||||||
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(sClientManagerThreadLocalIndex != kBadThreadLocalIndex);
|
||||||
|
RefPtr<ClientManager> cm =
|
||||||
|
static_cast<ClientManager*>(PR_GetThreadPrivate(sClientManagerThreadLocalIndex));
|
||||||
|
|
||||||
|
if (!cm) {
|
||||||
|
cm = new ClientManager();
|
||||||
|
|
||||||
|
PRStatus status =
|
||||||
|
PR_SetThreadPrivate(sClientManagerThreadLocalIndex, cm.get());
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(cm);
|
||||||
|
return cm.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkerPrivate*
|
||||||
|
ClientManager::GetWorkerPrivate() const
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientManager);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(GetActor());
|
||||||
|
return GetActor()->GetWorkerPrivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void
|
||||||
|
ClientManager::Startup()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
PRStatus status =
|
||||||
|
PR_NewThreadPrivateIndex(&sClientManagerThreadLocalIndex, nullptr);
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(status == PR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
UniquePtr<ClientSource>
|
||||||
|
ClientManager::CreateSource(ClientType aType, nsIPrincipal* aPrincipal)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(aPrincipal);
|
||||||
|
|
||||||
|
PrincipalInfo principalInfo;
|
||||||
|
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<ClientManager> mgr = GetOrCreateForCurrentThread();
|
||||||
|
return mgr->CreateSourceInternal(aType, principalInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
UniquePtr<ClientSource>
|
||||||
|
ClientManager::CreateSource(ClientType aType, const PrincipalInfo& aPrincipal)
|
||||||
|
{
|
||||||
|
RefPtr<ClientManager> mgr = GetOrCreateForCurrentThread();
|
||||||
|
return mgr->CreateSourceInternal(aType, aPrincipal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<ClientHandle>
|
||||||
|
ClientManager::CreateHandle(const ClientInfo& aClientInfo,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget)
|
||||||
|
{
|
||||||
|
RefPtr<ClientManager> mgr = GetOrCreateForCurrentThread();
|
||||||
|
return mgr->CreateHandleInternal(aClientInfo, aSerialEventTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,95 @@
|
||||||
|
/* -*- 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_ClientManager_h
|
||||||
|
#define _mozilla_dom_ClientManager_h
|
||||||
|
|
||||||
|
#include "mozilla/dom/ClientOpPromise.h"
|
||||||
|
#include "mozilla/dom/ClientThing.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace ipc {
|
||||||
|
class PBackgroundChild;
|
||||||
|
} // namespace ipc
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class ClientHandle;
|
||||||
|
class ClientInfo;
|
||||||
|
class ClientManagerChild;
|
||||||
|
class ClientOpConstructorArgs;
|
||||||
|
class ClientSource;
|
||||||
|
enum class ClientType : uint8_t;
|
||||||
|
|
||||||
|
namespace workers {
|
||||||
|
class WorkerPrivate;
|
||||||
|
} // workers namespace
|
||||||
|
|
||||||
|
// The ClientManager provides a per-thread singleton interface workering
|
||||||
|
// with the client subsystem. It allows globals to create ClientSource
|
||||||
|
// objects. It allows other parts of the system to attach to this globals
|
||||||
|
// by creating ClientHandle objects. The ClientManager also provides
|
||||||
|
// methods for querying the list of clients active in the system.
|
||||||
|
class ClientManager final : public ClientThing<ClientManagerChild>
|
||||||
|
{
|
||||||
|
friend class ClientManagerChild;
|
||||||
|
|
||||||
|
ClientManager();
|
||||||
|
~ClientManager();
|
||||||
|
|
||||||
|
// Utility method to trigger a shutdown of the ClientManager. This
|
||||||
|
// is called in various error conditions or when the last reference
|
||||||
|
// is dropped.
|
||||||
|
void
|
||||||
|
Shutdown();
|
||||||
|
|
||||||
|
UniquePtr<ClientSource>
|
||||||
|
CreateSourceInternal(ClientType aType,
|
||||||
|
const mozilla::ipc::PrincipalInfo& aPrincipal);
|
||||||
|
|
||||||
|
already_AddRefed<ClientHandle>
|
||||||
|
CreateHandleInternal(const ClientInfo& aClientInfo,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget);
|
||||||
|
|
||||||
|
// Utility method to perform an IPC operation. This will create a
|
||||||
|
// PClientManagerOp actor tied to a MozPromise. The promise will
|
||||||
|
// resolve or reject with the result of the remote operation.
|
||||||
|
already_AddRefed<ClientOpPromise>
|
||||||
|
StartOp(const ClientOpConstructorArgs& aArgs,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget);
|
||||||
|
|
||||||
|
// Get or create the TLS singleton. Currently this is only used
|
||||||
|
// internally and external code indirectly calls it by invoking
|
||||||
|
// static methods.
|
||||||
|
static already_AddRefed<ClientManager>
|
||||||
|
GetOrCreateForCurrentThread();
|
||||||
|
|
||||||
|
// Private methods called by ClientSource
|
||||||
|
mozilla::dom::workers::WorkerPrivate*
|
||||||
|
GetWorkerPrivate() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Initialize the ClientManager at process start. This
|
||||||
|
// does book-keeping like creating a TLS identifier, etc.
|
||||||
|
// This should only be called by process startup code.
|
||||||
|
static void
|
||||||
|
Startup();
|
||||||
|
|
||||||
|
static UniquePtr<ClientSource>
|
||||||
|
CreateSource(ClientType aType, nsIPrincipal* aPrincipal);
|
||||||
|
|
||||||
|
static UniquePtr<ClientSource>
|
||||||
|
CreateSource(ClientType aType, const mozilla::ipc::PrincipalInfo& aPrincipal);
|
||||||
|
|
||||||
|
static already_AddRefed<ClientHandle>
|
||||||
|
CreateHandle(const ClientInfo& aClientInfo,
|
||||||
|
nsISerialEventTarget* aSerialEventTarget);
|
||||||
|
|
||||||
|
NS_INLINE_DECL_REFCOUNTING(mozilla::dom::ClientManager)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // _mozilla_dom_ClientManager_h
|
|
@ -14,6 +14,12 @@ ClientManagerOpParent::ActorDestroy(ActorDestroyReason aReason)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClientManagerOpParent::ClientManagerOpParent(ClientManagerService* aService)
|
||||||
|
: mService(aService)
|
||||||
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mService);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ClientManagerOpParent::Init(const ClientOpConstructorArgs& aArgs)
|
ClientManagerOpParent::Init(const ClientOpConstructorArgs& aArgs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,12 +15,14 @@ class ClientManagerService;
|
||||||
|
|
||||||
class ClientManagerOpParent final : public PClientManagerOpParent
|
class ClientManagerOpParent final : public PClientManagerOpParent
|
||||||
{
|
{
|
||||||
|
RefPtr<ClientManagerService> mService;
|
||||||
|
|
||||||
// PClientManagerOpParent interface
|
// PClientManagerOpParent interface
|
||||||
void
|
void
|
||||||
ActorDestroy(ActorDestroyReason aReason) override;
|
ActorDestroy(ActorDestroyReason aReason) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClientManagerOpParent() = default;
|
explicit ClientManagerOpParent(ClientManagerService* aService);
|
||||||
~ClientManagerOpParent() = default;
|
~ClientManagerOpParent() = default;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "ClientHandleParent.h"
|
#include "ClientHandleParent.h"
|
||||||
#include "ClientManagerOpParent.h"
|
#include "ClientManagerOpParent.h"
|
||||||
|
#include "ClientManagerService.h"
|
||||||
#include "ClientSourceParent.h"
|
#include "ClientSourceParent.h"
|
||||||
#include "mozilla/dom/PClientNavigateOpParent.h"
|
#include "mozilla/dom/PClientNavigateOpParent.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
@ -54,7 +55,7 @@ ClientManagerParent::RecvPClientHandleConstructor(PClientHandleParent* aActor,
|
||||||
PClientManagerOpParent*
|
PClientManagerOpParent*
|
||||||
ClientManagerParent::AllocPClientManagerOpParent(const ClientOpConstructorArgs& aArgs)
|
ClientManagerParent::AllocPClientManagerOpParent(const ClientOpConstructorArgs& aArgs)
|
||||||
{
|
{
|
||||||
return new ClientManagerOpParent();
|
return new ClientManagerOpParent(mService);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -101,6 +102,7 @@ ClientManagerParent::DeallocPClientSourceParent(PClientSourceParent* aActor)
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientManagerParent::ClientManagerParent()
|
ClientManagerParent::ClientManagerParent()
|
||||||
|
: mService(ClientManagerService::GetOrCreateInstance())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,12 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class ClientManagerService;
|
||||||
|
|
||||||
class ClientManagerParent final : public PClientManagerParent
|
class ClientManagerParent final : public PClientManagerParent
|
||||||
{
|
{
|
||||||
|
RefPtr<ClientManagerService> mService;
|
||||||
|
|
||||||
// PClientManagerParent interface
|
// PClientManagerParent interface
|
||||||
mozilla::ipc::IPCResult
|
mozilla::ipc::IPCResult
|
||||||
RecvTeardown() override;
|
RecvTeardown() override;
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/* -*- 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 "ClientManagerService.h"
|
||||||
|
|
||||||
|
#include "mozilla/ipc/BackgroundParent.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
using mozilla::ipc::AssertIsOnBackgroundThread;
|
||||||
|
using mozilla::ipc::ContentPrincipalInfo;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
ClientManagerService* sClientManagerServiceInstance = nullptr;
|
||||||
|
|
||||||
|
bool
|
||||||
|
MatchPrincipalInfo(const PrincipalInfo& aLeft, const PrincipalInfo& aRight)
|
||||||
|
{
|
||||||
|
if (aLeft.type() != aRight.type()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (aLeft.type()) {
|
||||||
|
case PrincipalInfo::TContentPrincipalInfo:
|
||||||
|
{
|
||||||
|
const ContentPrincipalInfo& leftContent = aLeft.get_ContentPrincipalInfo();
|
||||||
|
const ContentPrincipalInfo& rightContent = aRight.get_ContentPrincipalInfo();
|
||||||
|
return leftContent.attrs() == rightContent.attrs() &&
|
||||||
|
leftContent.originNoSuffix() == rightContent.originNoSuffix();
|
||||||
|
}
|
||||||
|
case PrincipalInfo::TSystemPrincipalInfo:
|
||||||
|
{
|
||||||
|
// system principal always matches
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case PrincipalInfo::TNullPrincipalInfo:
|
||||||
|
{
|
||||||
|
// null principal never matches
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clients (windows/workers) should never have an expanded principal type.
|
||||||
|
MOZ_CRASH("unexpected principal type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
ClientManagerService::ClientManagerService()
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientManagerService::~ClientManagerService()
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mSourceTable.Count() == 0);
|
||||||
|
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(sClientManagerServiceInstance == this);
|
||||||
|
sClientManagerServiceInstance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<ClientManagerService>
|
||||||
|
ClientManagerService::GetOrCreateInstance()
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
if (!sClientManagerServiceInstance) {
|
||||||
|
sClientManagerServiceInstance = new ClientManagerService();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<ClientManagerService> ref(sClientManagerServiceInstance);
|
||||||
|
return ref.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientManagerService::AddSource(ClientSourceParent* aSource)
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(aSource);
|
||||||
|
auto entry = mSourceTable.LookupForAdd(aSource->Info().Id());
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(!entry);
|
||||||
|
entry.OrInsert([&] { return aSource; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientManagerService::RemoveSource(ClientSourceParent* aSource)
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
MOZ_ASSERT(aSource);
|
||||||
|
auto entry = mSourceTable.Lookup(aSource->Info().Id());
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(entry);
|
||||||
|
entry.Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSourceParent*
|
||||||
|
ClientManagerService::FindSource(const nsID& aID, const PrincipalInfo& aPrincipalInfo)
|
||||||
|
{
|
||||||
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
|
auto entry = mSourceTable.Lookup(aID);
|
||||||
|
if (!entry) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSourceParent* source = entry.Data();
|
||||||
|
if (!MatchPrincipalInfo(source->Info().PrincipalInfo(), aPrincipalInfo)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* -*- 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_ClientManagerService_h
|
||||||
|
#define _mozilla_dom_ClientManagerService_h
|
||||||
|
|
||||||
|
#include "nsDataHashtable.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class ClientSourceParent;
|
||||||
|
|
||||||
|
// Define a singleton service to manage client activity throughout the
|
||||||
|
// browser. This service runs on the PBackground thread. To interact
|
||||||
|
// it with it please use the ClientManager and ClientHandle classes.
|
||||||
|
class ClientManagerService final
|
||||||
|
{
|
||||||
|
// Store the ClientSourceParent objects in a hash table. We want to
|
||||||
|
// optimize for insertion, removal, and lookup by UUID.
|
||||||
|
nsDataHashtable<nsIDHashKey, ClientSourceParent*> mSourceTable;
|
||||||
|
|
||||||
|
ClientManagerService();
|
||||||
|
~ClientManagerService();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static already_AddRefed<ClientManagerService>
|
||||||
|
GetOrCreateInstance();
|
||||||
|
|
||||||
|
void
|
||||||
|
AddSource(ClientSourceParent* aSource);
|
||||||
|
|
||||||
|
void
|
||||||
|
RemoveSource(ClientSourceParent* aSource);
|
||||||
|
|
||||||
|
ClientSourceParent*
|
||||||
|
FindSource(const nsID& aID,
|
||||||
|
const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
|
||||||
|
|
||||||
|
NS_INLINE_DECL_REFCOUNTING(mozilla::dom::ClientManagerService)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // _mozilla_dom_ClientManagerService_h
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* -*- 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 "ClientSource.h"
|
||||||
|
|
||||||
|
#include "ClientManager.h"
|
||||||
|
#include "ClientManagerChild.h"
|
||||||
|
#include "ClientSourceChild.h"
|
||||||
|
#include "mozilla/dom/ClientIPCTypes.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
using mozilla::ipc::PrincipalInfo;
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientSource::Shutdown()
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientSource);
|
||||||
|
if (IsShutdown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShutdownThing();
|
||||||
|
|
||||||
|
mManager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSource::ClientSource(ClientManager* aManager,
|
||||||
|
const ClientSourceConstructorArgs& aArgs)
|
||||||
|
: mManager(aManager)
|
||||||
|
, mClientInfo(aArgs.id(), aArgs.type(), aArgs.principalInfo(), aArgs.creationTime())
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientSource::Activate(PClientManagerChild* aActor)
|
||||||
|
{
|
||||||
|
NS_ASSERT_OWNINGTHREAD(ClientSource);
|
||||||
|
MOZ_ASSERT(!GetActor());
|
||||||
|
|
||||||
|
if (IsShutdown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSourceConstructorArgs args(mClientInfo.Id(), mClientInfo.Type(),
|
||||||
|
mClientInfo.PrincipalInfo(),
|
||||||
|
mClientInfo.CreationTime());
|
||||||
|
PClientSourceChild* actor = aActor->SendPClientSourceConstructor(args);
|
||||||
|
if (!actor) {
|
||||||
|
Shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivateThing(static_cast<ClientSourceChild*>(actor));
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientSource::~ClientSource()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* -*- 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_ClientSource_h
|
||||||
|
#define _mozilla_dom_ClientSource_h
|
||||||
|
|
||||||
|
#include "mozilla/dom/ClientInfo.h"
|
||||||
|
#include "mozilla/dom/ClientThing.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class ClientManager;
|
||||||
|
class ClientSourceChild;
|
||||||
|
class ClientSourceConstructorArgs;
|
||||||
|
class PClientManagerChild;
|
||||||
|
|
||||||
|
namespace workers {
|
||||||
|
class WorkerPrivate;
|
||||||
|
} // workers namespace
|
||||||
|
|
||||||
|
// ClientSource is an RAII style class that is designed to be held via
|
||||||
|
// a UniquePtr<>. When created ClientSource will register the existence
|
||||||
|
// of a client in the cross-process ClientManagerService. When the
|
||||||
|
// ClientSource is destroyed then client entry will be removed. Code
|
||||||
|
// that represents globals or browsing environments, such as nsGlobalWindow
|
||||||
|
// or WorkerPrivate, should use ClientManager to create a ClientSource.
|
||||||
|
class ClientSource final : public ClientThing<ClientSourceChild>
|
||||||
|
{
|
||||||
|
friend class ClientManager;
|
||||||
|
|
||||||
|
NS_DECL_OWNINGTHREAD
|
||||||
|
|
||||||
|
RefPtr<ClientManager> mManager;
|
||||||
|
|
||||||
|
ClientInfo mClientInfo;
|
||||||
|
|
||||||
|
void
|
||||||
|
Shutdown();
|
||||||
|
|
||||||
|
// Private methods called by ClientManager
|
||||||
|
ClientSource(ClientManager* aManager,
|
||||||
|
const ClientSourceConstructorArgs& aArgs);
|
||||||
|
|
||||||
|
void
|
||||||
|
Activate(PClientManagerChild* aActor);
|
||||||
|
|
||||||
|
public:
|
||||||
|
~ClientSource();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // _mozilla_dom_ClientSource_h
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ClientSourceChild.h"
|
#include "ClientSourceChild.h"
|
||||||
|
|
||||||
#include "ClientSourceOpChild.h"
|
#include "ClientSourceOpChild.h"
|
||||||
|
#include "ClientThing.h"
|
||||||
#include "mozilla/dom/ClientIPCTypes.h"
|
#include "mozilla/dom/ClientIPCTypes.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ClientSourceParent.h"
|
#include "ClientSourceParent.h"
|
||||||
|
|
||||||
#include "ClientHandleParent.h"
|
#include "ClientHandleParent.h"
|
||||||
|
#include "ClientManagerService.h"
|
||||||
#include "ClientSourceOpParent.h"
|
#include "ClientSourceOpParent.h"
|
||||||
#include "mozilla/dom/ClientIPCTypes.h"
|
#include "mozilla/dom/ClientIPCTypes.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
|
@ -27,6 +28,15 @@ ClientSourceParent::RecvTeardown()
|
||||||
void
|
void
|
||||||
ClientSourceParent::ActorDestroy(ActorDestroyReason aReason)
|
ClientSourceParent::ActorDestroy(ActorDestroyReason aReason)
|
||||||
{
|
{
|
||||||
|
mService->RemoveSource(this);
|
||||||
|
|
||||||
|
nsTArray<ClientHandleParent*> handleList(mHandleList);
|
||||||
|
for (ClientHandleParent* handle : handleList) {
|
||||||
|
// This should trigger DetachHandle() to be called removing
|
||||||
|
// the entry from the mHandleList.
|
||||||
|
Unused << ClientHandleParent::Send__delete__(handle);
|
||||||
|
}
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mHandleList.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
PClientSourceOpParent*
|
PClientSourceOpParent*
|
||||||
|
@ -44,11 +54,37 @@ ClientSourceParent::DeallocPClientSourceOpParent(PClientSourceOpParent* aActor)
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientSourceParent::ClientSourceParent(const ClientSourceConstructorArgs& aArgs)
|
ClientSourceParent::ClientSourceParent(const ClientSourceConstructorArgs& aArgs)
|
||||||
|
: mClientInfo(aArgs.id(), aArgs.type(), aArgs.principalInfo(), aArgs.creationTime())
|
||||||
|
, mService(ClientManagerService::GetOrCreateInstance())
|
||||||
{
|
{
|
||||||
|
mService->AddSource(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientSourceParent::~ClientSourceParent()
|
ClientSourceParent::~ClientSourceParent()
|
||||||
{
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mHandleList.IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
const ClientInfo&
|
||||||
|
ClientSourceParent::Info() const
|
||||||
|
{
|
||||||
|
return mClientInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientSourceParent::AttachHandle(ClientHandleParent* aClientHandle)
|
||||||
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aClientHandle);
|
||||||
|
MOZ_ASSERT(!mHandleList.Contains(aClientHandle));
|
||||||
|
mHandleList.AppendElement(aClientHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClientSourceParent::DetachHandle(ClientHandleParent* aClientHandle)
|
||||||
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aClientHandle);
|
||||||
|
MOZ_ASSERT(mHandleList.Contains(aClientHandle));
|
||||||
|
mHandleList.RemoveElement(aClientHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -6,13 +6,21 @@
|
||||||
#ifndef _mozilla_dom_ClientSourceParent_h
|
#ifndef _mozilla_dom_ClientSourceParent_h
|
||||||
#define _mozilla_dom_ClientSourceParent_h
|
#define _mozilla_dom_ClientSourceParent_h
|
||||||
|
|
||||||
|
#include "ClientInfo.h"
|
||||||
#include "mozilla/dom/PClientSourceParent.h"
|
#include "mozilla/dom/PClientSourceParent.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class ClientHandleParent;
|
||||||
|
class ClientManagerService;
|
||||||
|
|
||||||
class ClientSourceParent final : public PClientSourceParent
|
class ClientSourceParent final : public PClientSourceParent
|
||||||
{
|
{
|
||||||
|
ClientInfo mClientInfo;
|
||||||
|
RefPtr<ClientManagerService> mService;
|
||||||
|
nsTArray<ClientHandleParent*> mHandleList;
|
||||||
|
|
||||||
// PClientSourceParent
|
// PClientSourceParent
|
||||||
IPCResult
|
IPCResult
|
||||||
RecvTeardown() override;
|
RecvTeardown() override;
|
||||||
|
@ -29,6 +37,15 @@ class ClientSourceParent final : public PClientSourceParent
|
||||||
public:
|
public:
|
||||||
explicit ClientSourceParent(const ClientSourceConstructorArgs& aArgs);
|
explicit ClientSourceParent(const ClientSourceConstructorArgs& aArgs);
|
||||||
~ClientSourceParent();
|
~ClientSourceParent();
|
||||||
|
|
||||||
|
const ClientInfo&
|
||||||
|
Info() const;
|
||||||
|
|
||||||
|
void
|
||||||
|
AttachHandle(ClientHandleParent* aClientSource);
|
||||||
|
|
||||||
|
void
|
||||||
|
DetachHandle(ClientHandleParent* aClientSource);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -99,6 +99,11 @@ public:
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
|
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
|
||||||
mActor->RevokeOwner(this);
|
mActor->RevokeOwner(this);
|
||||||
mActor = nullptr;
|
mActor = nullptr;
|
||||||
|
|
||||||
|
// Also consider the ClientThing shutdown. We simply set the flag
|
||||||
|
// instead of calling ShutdownThing() to avoid calling MaybeStartTeardown()
|
||||||
|
// on the destroyed actor.
|
||||||
|
mShutdown = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,31 +5,38 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
EXPORTS.mozilla.dom += [
|
EXPORTS.mozilla.dom += [
|
||||||
|
'ClientHandle.h',
|
||||||
'ClientInfo.h',
|
'ClientInfo.h',
|
||||||
'ClientIPCUtils.h',
|
'ClientIPCUtils.h',
|
||||||
|
'ClientManager.h',
|
||||||
'ClientManagerActors.h',
|
'ClientManagerActors.h',
|
||||||
'ClientOpenWindowOpActors.h',
|
'ClientOpenWindowOpActors.h',
|
||||||
'ClientOpPromise.h',
|
'ClientOpPromise.h',
|
||||||
|
'ClientSource.h',
|
||||||
'ClientState.h',
|
'ClientState.h',
|
||||||
'ClientThing.h',
|
'ClientThing.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
|
'ClientHandle.cpp',
|
||||||
'ClientHandleChild.cpp',
|
'ClientHandleChild.cpp',
|
||||||
'ClientHandleOpChild.cpp',
|
'ClientHandleOpChild.cpp',
|
||||||
'ClientHandleOpParent.cpp',
|
'ClientHandleOpParent.cpp',
|
||||||
'ClientHandleParent.cpp',
|
'ClientHandleParent.cpp',
|
||||||
'ClientInfo.cpp',
|
'ClientInfo.cpp',
|
||||||
|
'ClientManager.cpp',
|
||||||
'ClientManagerActors.cpp',
|
'ClientManagerActors.cpp',
|
||||||
'ClientManagerChild.cpp',
|
'ClientManagerChild.cpp',
|
||||||
'ClientManagerOpChild.cpp',
|
'ClientManagerOpChild.cpp',
|
||||||
'ClientManagerOpParent.cpp',
|
'ClientManagerOpParent.cpp',
|
||||||
'ClientManagerParent.cpp',
|
'ClientManagerParent.cpp',
|
||||||
|
'ClientManagerService.cpp',
|
||||||
'ClientNavigateOpChild.cpp',
|
'ClientNavigateOpChild.cpp',
|
||||||
'ClientNavigateOpParent.cpp',
|
'ClientNavigateOpParent.cpp',
|
||||||
'ClientOpenWindowOpActors.cpp',
|
'ClientOpenWindowOpActors.cpp',
|
||||||
'ClientOpenWindowOpChild.cpp',
|
'ClientOpenWindowOpChild.cpp',
|
||||||
'ClientOpenWindowOpParent.cpp',
|
'ClientOpenWindowOpParent.cpp',
|
||||||
|
'ClientSource.cpp',
|
||||||
'ClientSourceChild.cpp',
|
'ClientSourceChild.cpp',
|
||||||
'ClientSourceOpChild.cpp',
|
'ClientSourceOpChild.cpp',
|
||||||
'ClientSourceOpParent.cpp',
|
'ClientSourceOpParent.cpp',
|
||||||
|
@ -52,6 +59,7 @@ IPDL_SOURCES += [
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
'/dom/workers',
|
||||||
]
|
]
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "mozilla/TelemetryIPC.h"
|
#include "mozilla/TelemetryIPC.h"
|
||||||
#include "mozilla/devtools/HeapSnapshotTempFileHelperChild.h"
|
#include "mozilla/devtools/HeapSnapshotTempFileHelperChild.h"
|
||||||
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
|
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
|
||||||
|
#include "mozilla/dom/ClientManager.h"
|
||||||
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
||||||
#include "mozilla/dom/ContentBridgeChild.h"
|
#include "mozilla/dom/ContentBridgeChild.h"
|
||||||
#include "mozilla/dom/ContentBridgeParent.h"
|
#include "mozilla/dom/ContentBridgeParent.h"
|
||||||
|
@ -1154,6 +1155,8 @@ ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClientManager::Startup();
|
||||||
|
|
||||||
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
NS_WARNING("Couldn't acquire console service");
|
NS_WARNING("Couldn't acquire console service");
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "mozilla/DataStorage.h"
|
#include "mozilla/DataStorage.h"
|
||||||
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
||||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||||
|
#include "mozilla/dom/ClientManager.h"
|
||||||
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
||||||
#include "mozilla/dom/DataTransfer.h"
|
#include "mozilla/dom/DataTransfer.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
|
@ -628,6 +629,7 @@ ContentParent::StartUp()
|
||||||
mozilla::dom::time::InitializeDateCacheCleaner();
|
mozilla::dom::time::InitializeDateCacheCleaner();
|
||||||
|
|
||||||
BackgroundChild::Startup();
|
BackgroundChild::Startup();
|
||||||
|
ClientManager::Startup();
|
||||||
|
|
||||||
sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
|
sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
try {
|
||||||
|
WebAssembly.compileStreaming();
|
||||||
|
} catch (err) {
|
||||||
|
assertEq(String(err).indexOf("not supported with --no-threads") !== -1, true);
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
if (!this.oomAfterAllocations)
|
||||||
|
quit();
|
||||||
|
oomAfterAllocations(1, 2);
|
||||||
|
var x = wasmTextToBinary('(module (func (export "run") (result i32) i32.const 42))');
|
||||||
|
WebAssembly.compileStreaming(x);
|
||||||
|
drainJobQueue();
|
|
@ -135,8 +135,7 @@ js::WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleOb
|
||||||
RootedFunction wrapped(cx, NewFunctionWithProto(cx, WrappedAsyncFunction, length,
|
RootedFunction wrapped(cx, NewFunctionWithProto(cx, WrappedAsyncFunction, length,
|
||||||
JSFunction::NATIVE_FUN, nullptr,
|
JSFunction::NATIVE_FUN, nullptr,
|
||||||
funName, proto,
|
funName, proto,
|
||||||
AllocKind::FUNCTION_EXTENDED,
|
AllocKind::FUNCTION_EXTENDED));
|
||||||
TenuredObject));
|
|
||||||
if (!wrapped)
|
if (!wrapped)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,7 @@ js::WrapAsyncGeneratorWithProto(JSContext* cx, HandleFunction unwrapped, HandleO
|
||||||
RootedFunction wrapped(cx, NewFunctionWithProto(cx, WrappedAsyncGenerator, length,
|
RootedFunction wrapped(cx, NewFunctionWithProto(cx, WrappedAsyncGenerator, length,
|
||||||
JSFunction::NATIVE_FUN, nullptr,
|
JSFunction::NATIVE_FUN, nullptr,
|
||||||
funName, proto,
|
funName, proto,
|
||||||
AllocKind::FUNCTION_EXTENDED,
|
AllocKind::FUNCTION_EXTENDED));
|
||||||
TenuredObject));
|
|
||||||
if (!wrapped)
|
if (!wrapped)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
|
@ -1851,17 +1851,25 @@ WebAssembly_toSource(JSContext* cx, unsigned argc, Value* vp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool
|
||||||
|
RejectWithPendingException(JSContext* cx, Handle<PromiseObject*> promise)
|
||||||
|
{
|
||||||
|
if (!cx->isExceptionPending())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RootedValue rejectionValue(cx);
|
||||||
|
if (!GetAndClearException(cx, &rejectionValue))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return PromiseObject::reject(cx, promise, rejectionValue);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
Reject(JSContext* cx, const CompileArgs& args, UniqueChars error, Handle<PromiseObject*> promise)
|
Reject(JSContext* cx, const CompileArgs& args, UniqueChars error, Handle<PromiseObject*> promise)
|
||||||
{
|
{
|
||||||
if (!error) {
|
if (!error) {
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
|
return RejectWithPendingException(cx, promise);
|
||||||
RootedValue rejectionValue(cx);
|
|
||||||
if (!cx->getPendingException(&rejectionValue))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return PromiseObject::reject(cx, promise, rejectionValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedObject stack(cx, promise->allocationSite());
|
RootedObject stack(cx, promise->allocationSite());
|
||||||
|
@ -1892,19 +1900,6 @@ Reject(JSContext* cx, const CompileArgs& args, UniqueChars error, Handle<Promise
|
||||||
return PromiseObject::reject(cx, promise, rejectionValue);
|
return PromiseObject::reject(cx, promise, rejectionValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
RejectWithPendingException(JSContext* cx, Handle<PromiseObject*> promise)
|
|
||||||
{
|
|
||||||
if (!cx->isExceptionPending())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
RootedValue rejectionValue(cx);
|
|
||||||
if (!GetAndClearException(cx, &rejectionValue))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return PromiseObject::reject(cx, promise, rejectionValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
Resolve(JSContext* cx, Module& module, const CompileArgs& compileArgs,
|
Resolve(JSContext* cx, Module& module, const CompileArgs& compileArgs,
|
||||||
Handle<PromiseObject*> promise, bool instantiate, HandleObject importObj)
|
Handle<PromiseObject*> promise, bool instantiate, HandleObject importObj)
|
||||||
|
@ -2522,7 +2517,7 @@ ResolveResponse(JSContext* cx, CallArgs callArgs, Handle<PromiseObject*> promise
|
||||||
|
|
||||||
RootedFunction onRejected(cx, NewNativeFunction(cx, ResolveResponse_OnRejected, 1, nullptr,
|
RootedFunction onRejected(cx, NewNativeFunction(cx, ResolveResponse_OnRejected, 1, nullptr,
|
||||||
gc::AllocKind::FUNCTION_EXTENDED));
|
gc::AllocKind::FUNCTION_EXTENDED));
|
||||||
if (!onResolved)
|
if (!onRejected)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
onResolved->setExtendedSlot(0, ObjectValue(*closure));
|
onResolved->setExtendedSlot(0, ObjectValue(*closure));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче