зеркало из 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 "ClientHandleOpParent.h"
|
||||
#include "ClientManagerService.h"
|
||||
#include "ClientSourceParent.h"
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -26,6 +27,10 @@ ClientHandleParent::RecvTeardown()
|
|||
void
|
||||
ClientHandleParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
if (mSource) {
|
||||
mSource->DetachHandle(this);
|
||||
mSource = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PClientHandleOpParent*
|
||||
|
@ -51,16 +56,32 @@ ClientHandleParent::RecvPClientHandleOpConstructor(PClientHandleOpParent* aActor
|
|||
}
|
||||
|
||||
ClientHandleParent::ClientHandleParent()
|
||||
: mService(ClientManagerService::GetOrCreateInstance())
|
||||
, mSource(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ClientHandleParent::~ClientHandleParent()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mSource);
|
||||
}
|
||||
|
||||
void
|
||||
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
|
||||
|
|
|
@ -11,8 +11,14 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ClientManagerService;
|
||||
class ClientSourceParent;
|
||||
|
||||
class ClientHandleParent final : public PClientHandleParent
|
||||
{
|
||||
RefPtr<ClientManagerService> mService;
|
||||
ClientSourceParent* mSource;
|
||||
|
||||
// PClientHandleParent interface
|
||||
mozilla::ipc::IPCResult
|
||||
RecvTeardown() override;
|
||||
|
@ -36,6 +42,9 @@ public:
|
|||
|
||||
void
|
||||
Init(const IPCClientInfo& aClientInfo);
|
||||
|
||||
ClientSourceParent*
|
||||
GetSource() const;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -17,6 +17,10 @@ namespace dom {
|
|||
|
||||
struct ClientSourceConstructorArgs
|
||||
{
|
||||
nsID id;
|
||||
ClientType type;
|
||||
PrincipalInfo principalInfo;
|
||||
TimeStamp creationTime;
|
||||
};
|
||||
|
||||
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
|
||||
ClientManagerOpParent::Init(const ClientOpConstructorArgs& aArgs)
|
||||
{
|
||||
|
|
|
@ -15,12 +15,14 @@ class ClientManagerService;
|
|||
|
||||
class ClientManagerOpParent final : public PClientManagerOpParent
|
||||
{
|
||||
RefPtr<ClientManagerService> mService;
|
||||
|
||||
// PClientManagerOpParent interface
|
||||
void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
public:
|
||||
ClientManagerOpParent() = default;
|
||||
explicit ClientManagerOpParent(ClientManagerService* aService);
|
||||
~ClientManagerOpParent() = default;
|
||||
|
||||
void
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "ClientHandleParent.h"
|
||||
#include "ClientManagerOpParent.h"
|
||||
#include "ClientManagerService.h"
|
||||
#include "ClientSourceParent.h"
|
||||
#include "mozilla/dom/PClientNavigateOpParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -54,7 +55,7 @@ ClientManagerParent::RecvPClientHandleConstructor(PClientHandleParent* aActor,
|
|||
PClientManagerOpParent*
|
||||
ClientManagerParent::AllocPClientManagerOpParent(const ClientOpConstructorArgs& aArgs)
|
||||
{
|
||||
return new ClientManagerOpParent();
|
||||
return new ClientManagerOpParent(mService);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -101,6 +102,7 @@ ClientManagerParent::DeallocPClientSourceParent(PClientSourceParent* aActor)
|
|||
}
|
||||
|
||||
ClientManagerParent::ClientManagerParent()
|
||||
: mService(ClientManagerService::GetOrCreateInstance())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,12 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ClientManagerService;
|
||||
|
||||
class ClientManagerParent final : public PClientManagerParent
|
||||
{
|
||||
RefPtr<ClientManagerService> mService;
|
||||
|
||||
// PClientManagerParent interface
|
||||
mozilla::ipc::IPCResult
|
||||
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 "ClientSourceOpChild.h"
|
||||
#include "ClientThing.h"
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "ClientSourceParent.h"
|
||||
|
||||
#include "ClientHandleParent.h"
|
||||
#include "ClientManagerService.h"
|
||||
#include "ClientSourceOpParent.h"
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -27,6 +28,15 @@ ClientSourceParent::RecvTeardown()
|
|||
void
|
||||
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*
|
||||
|
@ -44,11 +54,37 @@ ClientSourceParent::DeallocPClientSourceOpParent(PClientSourceOpParent* aActor)
|
|||
}
|
||||
|
||||
ClientSourceParent::ClientSourceParent(const ClientSourceConstructorArgs& aArgs)
|
||||
: mClientInfo(aArgs.id(), aArgs.type(), aArgs.principalInfo(), aArgs.creationTime())
|
||||
, mService(ClientManagerService::GetOrCreateInstance())
|
||||
{
|
||||
mService->AddSource(this);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -6,13 +6,21 @@
|
|||
#ifndef _mozilla_dom_ClientSourceParent_h
|
||||
#define _mozilla_dom_ClientSourceParent_h
|
||||
|
||||
#include "ClientInfo.h"
|
||||
#include "mozilla/dom/PClientSourceParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ClientHandleParent;
|
||||
class ClientManagerService;
|
||||
|
||||
class ClientSourceParent final : public PClientSourceParent
|
||||
{
|
||||
ClientInfo mClientInfo;
|
||||
RefPtr<ClientManagerService> mService;
|
||||
nsTArray<ClientHandleParent*> mHandleList;
|
||||
|
||||
// PClientSourceParent
|
||||
IPCResult
|
||||
RecvTeardown() override;
|
||||
|
@ -29,6 +37,15 @@ class ClientSourceParent final : public PClientSourceParent
|
|||
public:
|
||||
explicit ClientSourceParent(const ClientSourceConstructorArgs& aArgs);
|
||||
~ClientSourceParent();
|
||||
|
||||
const ClientInfo&
|
||||
Info() const;
|
||||
|
||||
void
|
||||
AttachHandle(ClientHandleParent* aClientSource);
|
||||
|
||||
void
|
||||
DetachHandle(ClientHandleParent* aClientSource);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -99,6 +99,11 @@ public:
|
|||
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
|
||||
mActor->RevokeOwner(this);
|
||||
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/.
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'ClientHandle.h',
|
||||
'ClientInfo.h',
|
||||
'ClientIPCUtils.h',
|
||||
'ClientManager.h',
|
||||
'ClientManagerActors.h',
|
||||
'ClientOpenWindowOpActors.h',
|
||||
'ClientOpPromise.h',
|
||||
'ClientSource.h',
|
||||
'ClientState.h',
|
||||
'ClientThing.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ClientHandle.cpp',
|
||||
'ClientHandleChild.cpp',
|
||||
'ClientHandleOpChild.cpp',
|
||||
'ClientHandleOpParent.cpp',
|
||||
'ClientHandleParent.cpp',
|
||||
'ClientInfo.cpp',
|
||||
'ClientManager.cpp',
|
||||
'ClientManagerActors.cpp',
|
||||
'ClientManagerChild.cpp',
|
||||
'ClientManagerOpChild.cpp',
|
||||
'ClientManagerOpParent.cpp',
|
||||
'ClientManagerParent.cpp',
|
||||
'ClientManagerService.cpp',
|
||||
'ClientNavigateOpChild.cpp',
|
||||
'ClientNavigateOpParent.cpp',
|
||||
'ClientOpenWindowOpActors.cpp',
|
||||
'ClientOpenWindowOpChild.cpp',
|
||||
'ClientOpenWindowOpParent.cpp',
|
||||
'ClientSource.cpp',
|
||||
'ClientSourceChild.cpp',
|
||||
'ClientSourceOpChild.cpp',
|
||||
'ClientSourceOpParent.cpp',
|
||||
|
@ -52,6 +59,7 @@ IPDL_SOURCES += [
|
|||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/workers',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "mozilla/TelemetryIPC.h"
|
||||
#include "mozilla/devtools/HeapSnapshotTempFileHelperChild.h"
|
||||
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
|
||||
#include "mozilla/dom/ClientManager.h"
|
||||
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
||||
#include "mozilla/dom/ContentBridgeChild.h"
|
||||
#include "mozilla/dom/ContentBridgeParent.h"
|
||||
|
@ -1154,6 +1155,8 @@ ContentChild::InitXPCOM(const XPCOMInitData& aXPCOMInit,
|
|||
return;
|
||||
}
|
||||
|
||||
ClientManager::Startup();
|
||||
|
||||
nsCOMPtr<nsIConsoleService> svc(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
if (!svc) {
|
||||
NS_WARNING("Couldn't acquire console service");
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "mozilla/DataStorage.h"
|
||||
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||
#include "mozilla/dom/ClientManager.h"
|
||||
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
||||
#include "mozilla/dom/DataTransfer.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -628,6 +629,7 @@ ContentParent::StartUp()
|
|||
mozilla::dom::time::InitializeDateCacheCleaner();
|
||||
|
||||
BackgroundChild::Startup();
|
||||
ClientManager::Startup();
|
||||
|
||||
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,
|
||||
JSFunction::NATIVE_FUN, nullptr,
|
||||
funName, proto,
|
||||
AllocKind::FUNCTION_EXTENDED,
|
||||
TenuredObject));
|
||||
AllocKind::FUNCTION_EXTENDED));
|
||||
if (!wrapped)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -80,8 +80,7 @@ js::WrapAsyncGeneratorWithProto(JSContext* cx, HandleFunction unwrapped, HandleO
|
|||
RootedFunction wrapped(cx, NewFunctionWithProto(cx, WrappedAsyncGenerator, length,
|
||||
JSFunction::NATIVE_FUN, nullptr,
|
||||
funName, proto,
|
||||
AllocKind::FUNCTION_EXTENDED,
|
||||
TenuredObject));
|
||||
AllocKind::FUNCTION_EXTENDED));
|
||||
if (!wrapped)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -1851,17 +1851,25 @@ WebAssembly_toSource(JSContext* cx, unsigned argc, Value* vp)
|
|||
}
|
||||
#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
|
||||
Reject(JSContext* cx, const CompileArgs& args, UniqueChars error, Handle<PromiseObject*> promise)
|
||||
{
|
||||
if (!error) {
|
||||
ReportOutOfMemory(cx);
|
||||
|
||||
RootedValue rejectionValue(cx);
|
||||
if (!cx->getPendingException(&rejectionValue))
|
||||
return false;
|
||||
|
||||
return PromiseObject::reject(cx, promise, rejectionValue);
|
||||
return RejectWithPendingException(cx, promise);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
Resolve(JSContext* cx, Module& module, const CompileArgs& compileArgs,
|
||||
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,
|
||||
gc::AllocKind::FUNCTION_EXTENDED));
|
||||
if (!onResolved)
|
||||
if (!onRejected)
|
||||
return false;
|
||||
|
||||
onResolved->setExtendedSlot(0, ObjectValue(*closure));
|
||||
|
|
Загрузка…
Ссылка в новой задаче