зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1250572 - Force a parent object in MessagePort/Channel and in StructuredCloneHolder, r=smaug
This commit is contained in:
Родитель
8b94dc47cb
Коммит
9e960ae549
|
@ -295,6 +295,7 @@ StructuredCloneHolder::Read(nsISupports* aParent,
|
|||
{
|
||||
MOZ_ASSERT_IF(mSupportedContext == SameProcessSameThread,
|
||||
mCreationThread == NS_GetCurrentThread());
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
mozilla::AutoRestore<nsISupports*> guard(mParent);
|
||||
mParent = aParent;
|
||||
|
@ -1044,9 +1045,11 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx,
|
|||
MOZ_ASSERT(aExtraData < mPortIdentifiers.Length());
|
||||
const MessagePortIdentifier& portIdentifier = mPortIdentifiers[aExtraData];
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mParent);
|
||||
|
||||
ErrorResult rv;
|
||||
RefPtr<MessagePort> port =
|
||||
MessagePort::Create(mParent, portIdentifier, rv);
|
||||
MessagePort::Create(global, portIdentifier, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MessageChannel, mWindow, mPort1, mPort2)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MessageChannel, mGlobal, mPort1, mPort2)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(MessageChannel)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(MessageChannel)
|
||||
|
||||
|
@ -29,9 +29,10 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageChannel)
|
|||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
MessageChannel::MessageChannel(nsPIDOMWindowInner* aWindow)
|
||||
: mWindow(aWindow)
|
||||
MessageChannel::MessageChannel(nsIGlobalObject* aGlobal)
|
||||
: mGlobal(aGlobal)
|
||||
{
|
||||
MOZ_ASSERT(aGlobal);
|
||||
}
|
||||
|
||||
MessageChannel::~MessageChannel()
|
||||
|
@ -47,14 +48,15 @@ MessageChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|||
/* static */ already_AddRefed<MessageChannel>
|
||||
MessageChannel::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
// window can be null in workers.
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
return Constructor(window, aRv);
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
return Constructor(global, aRv);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<MessageChannel>
|
||||
MessageChannel::Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv)
|
||||
MessageChannel::Constructor(nsIGlobalObject* aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aGlobal);
|
||||
|
||||
nsID portUUID1;
|
||||
aRv = nsContentUtils::GenerateUUIDInPlace(portUUID1);
|
||||
if (aRv.Failed()) {
|
||||
|
@ -67,14 +69,14 @@ MessageChannel::Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<MessageChannel> channel = new MessageChannel(aWindow);
|
||||
RefPtr<MessageChannel> channel = new MessageChannel(aGlobal);
|
||||
|
||||
channel->mPort1 = MessagePort::Create(aWindow, portUUID1, portUUID2, aRv);
|
||||
channel->mPort1 = MessagePort::Create(aGlobal, portUUID1, portUUID2, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
channel->mPort2 = MessagePort::Create(aWindow, portUUID2, portUUID1, aRv);
|
||||
channel->mPort2 = MessagePort::Create(aGlobal, portUUID2, portUUID1, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "nsWrapperCache.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -28,10 +28,10 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MessageChannel)
|
||||
|
||||
nsPIDOMWindowInner*
|
||||
nsIGlobalObject*
|
||||
GetParentObject() const
|
||||
{
|
||||
return mWindow;
|
||||
return mGlobal;
|
||||
}
|
||||
|
||||
virtual JSObject*
|
||||
|
@ -41,7 +41,7 @@ public:
|
|||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<MessageChannel>
|
||||
Constructor(nsPIDOMWindowInner* aWindow, ErrorResult& aRv);
|
||||
Constructor(nsIGlobalObject* aGlobal, ErrorResult& aRv);
|
||||
|
||||
MessagePort*
|
||||
Port1() const
|
||||
|
@ -56,10 +56,10 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
explicit MessageChannel(nsPIDOMWindowInner* aWindow);
|
||||
explicit MessageChannel(nsIGlobalObject* aGlobal);
|
||||
~MessageChannel();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
|
||||
RefPtr<MessagePort> mPort1;
|
||||
RefPtr<MessagePort> mPort2;
|
||||
|
|
|
@ -89,15 +89,8 @@ private:
|
|||
nsresult
|
||||
DispatchMessage() const
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> globalObject;
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
globalObject = do_QueryInterface(mPort->GetParentObject());
|
||||
} else {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
globalObject = workerPrivate->GlobalScope();
|
||||
}
|
||||
nsCOMPtr<nsIGlobalObject> globalObject = mPort->GetParentObject();
|
||||
MOZ_ASSERT(globalObject);
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
if (!globalObject || !jsapi.Init(globalObject)) {
|
||||
|
@ -282,20 +275,17 @@ NS_IMPL_ISUPPORTS(ForceCloseHelper, nsIIPCBackgroundChildCreateCallback)
|
|||
|
||||
} // namespace
|
||||
|
||||
MessagePort::MessagePort(nsISupports* aSupports)
|
||||
: mInnerID(0)
|
||||
MessagePort::MessagePort(nsIGlobalObject* aGlobal)
|
||||
: DOMEventTargetHelper(aGlobal)
|
||||
, mInnerID(0)
|
||||
, mMessageQueueEnabled(false)
|
||||
, mIsKeptAlive(false)
|
||||
{
|
||||
MOZ_ASSERT(aGlobal);
|
||||
|
||||
mIdentifier = new MessagePortIdentifier();
|
||||
mIdentifier->neutered() = true;
|
||||
mIdentifier->sequenceId() = 0;
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(aSupports);
|
||||
if (NS_WARN_IF(!globalObject)) {
|
||||
return;
|
||||
}
|
||||
BindToOwner(globalObject);
|
||||
}
|
||||
|
||||
MessagePort::~MessagePort()
|
||||
|
@ -305,21 +295,25 @@ MessagePort::~MessagePort()
|
|||
}
|
||||
|
||||
/* static */ already_AddRefed<MessagePort>
|
||||
MessagePort::Create(nsISupports* aSupport, const nsID& aUUID,
|
||||
MessagePort::Create(nsIGlobalObject* aGlobal, const nsID& aUUID,
|
||||
const nsID& aDestinationUUID, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<MessagePort> mp = new MessagePort(aSupport);
|
||||
MOZ_ASSERT(aGlobal);
|
||||
|
||||
RefPtr<MessagePort> mp = new MessagePort(aGlobal);
|
||||
mp->Initialize(aUUID, aDestinationUUID, 1 /* 0 is an invalid sequence ID */,
|
||||
false /* Neutered */, eStateUnshippedEntangled, aRv);
|
||||
return mp.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<MessagePort>
|
||||
MessagePort::Create(nsISupports* aSupport,
|
||||
MessagePort::Create(nsIGlobalObject* aGlobal,
|
||||
const MessagePortIdentifier& aIdentifier,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<MessagePort> mp = new MessagePort(aSupport);
|
||||
MOZ_ASSERT(aGlobal);
|
||||
|
||||
RefPtr<MessagePort> mp = new MessagePort(aGlobal);
|
||||
mp->Initialize(aIdentifier.uuid(), aIdentifier.destinationUuid(),
|
||||
aIdentifier.sequenceId(), aIdentifier.neutered(),
|
||||
eStateEntangling, aRv);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#undef PostMessage
|
||||
#endif
|
||||
|
||||
class nsPIDOMWindowInner;
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -45,11 +45,12 @@ public:
|
|||
DOMEventTargetHelper)
|
||||
|
||||
static already_AddRefed<MessagePort>
|
||||
Create(nsISupports* aSupport, const nsID& aUUID,
|
||||
Create(nsIGlobalObject* aGlobal, const nsID& aUUID,
|
||||
const nsID& aDestinationUUID, ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<MessagePort>
|
||||
Create(nsISupports* aSupport, const MessagePortIdentifier& aIdentifier,
|
||||
Create(nsIGlobalObject* aGlobal,
|
||||
const MessagePortIdentifier& aIdentifier,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// For IPC.
|
||||
|
@ -88,7 +89,7 @@ public:
|
|||
void Closed();
|
||||
|
||||
private:
|
||||
explicit MessagePort(nsISupports* nsISupports);
|
||||
explicit MessagePort(nsIGlobalObject* aGlobal);
|
||||
~MessagePort();
|
||||
|
||||
enum State {
|
||||
|
|
|
@ -2288,13 +2288,14 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx,
|
|||
|
||||
// We don't actually care about this MessageChannel, but we use it to 'steal'
|
||||
// its 2 connected ports.
|
||||
RefPtr<MessageChannel> channel = MessageChannel::Constructor(window, rv);
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
|
||||
RefPtr<MessageChannel> channel = MessageChannel::Constructor(global, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
RefPtr<SharedWorker> sharedWorker = new SharedWorker(window, workerPrivate,
|
||||
channel->Port1());
|
||||
channel->Port1());
|
||||
|
||||
if (!workerPrivate->RegisterSharedWorker(sharedWorker, channel->Port2())) {
|
||||
NS_WARNING("Worker is unreachable, this shouldn't happen!");
|
||||
|
|
|
@ -668,11 +668,24 @@ public:
|
|||
DispatchDOMEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
DOMEventTargetHelper* aTarget, bool aIsMainThread)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> parent;
|
||||
if (aIsMainThread) {
|
||||
parent = do_QueryInterface(aTarget->GetParentObject());
|
||||
nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(aTarget->GetParentObject());
|
||||
|
||||
// For some workers without window, parent is null and we try to find it
|
||||
// from the JS Context.
|
||||
if (!parent) {
|
||||
JS::Rooted<JSObject*> globalObject(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
if (NS_WARN_IF(!globalObject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parent = xpc::NativeGlobal(globalObject);
|
||||
if (NS_WARN_IF(!parent)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
JS::Rooted<JS::Value> messageData(aCx);
|
||||
ErrorResult rv;
|
||||
|
||||
|
@ -6376,7 +6389,7 @@ WorkerPrivate::ConnectMessagePort(JSContext* aCx,
|
|||
// This MessagePortIdentifier is used to create a new port, still connected
|
||||
// with the other one, but in the worker thread.
|
||||
ErrorResult rv;
|
||||
RefPtr<MessagePort> port = MessagePort::Create(nullptr, aIdentifier, rv);
|
||||
RefPtr<MessagePort> port = MessagePort::Create(globalScope, aIdentifier, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsVariant.h"
|
||||
|
||||
#include "RuntimeService.h"
|
||||
#include "WorkerScope.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "XMLHttpRequestUpload.h"
|
||||
|
@ -1355,7 +1356,12 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
|
||||
ErrorResult rv;
|
||||
JS::Rooted<JS::Value> response(aCx);
|
||||
Read(nullptr, aCx, &response, rv);
|
||||
|
||||
GlobalObject globalObj(aCx, aWorkerPrivate->GlobalScope()->GetWrapper());
|
||||
nsCOMPtr<nsIGlobalObject> global =
|
||||
do_QueryInterface(globalObj.GetAsSupports());
|
||||
|
||||
Read(global, aCx, &response, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
|
@ -1532,8 +1538,18 @@ SendRunnable::MainThreadRun()
|
|||
|
||||
ErrorResult rv;
|
||||
|
||||
JS::Rooted<JSObject*> globalObject(cx, JS::CurrentGlobalOrNull(cx));
|
||||
if (NS_WARN_IF(!globalObject)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> parent = xpc::NativeGlobal(globalObject);
|
||||
if (NS_WARN_IF(!parent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> body(cx);
|
||||
Read(nullptr, cx, &body, rv);
|
||||
Read(parent, cx, &body, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче