зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1353629 - PBlob refactoring - part 3 - IPCBlob in ClonedMessageData, r=smaug
This is the first use of IPCBlob: ClonedMessageData. ClonedMessageData is used for BroadcastChannel, MessagePort and any postMessage() communication. This patch changes StructuredCloneData in order to use IPCBlob instead of PBlob. BroadcastChannel has a custom way to manage Blobs because when the parent receives them from a content process, it must send them to any other BroadcastChild actor duplicating the serialization.
This commit is contained in:
Родитель
189f9f2cca
Коммит
b42d5af54d
|
@ -7,8 +7,9 @@
|
||||||
#include "BroadcastChannelParent.h"
|
#include "BroadcastChannelParent.h"
|
||||||
#include "BroadcastChannelService.h"
|
#include "BroadcastChannelService.h"
|
||||||
#include "mozilla/dom/File.h"
|
#include "mozilla/dom/File.h"
|
||||||
#include "mozilla/dom/ipc/BlobParent.h"
|
#include "mozilla/dom/IPCBlobUtils.h"
|
||||||
#include "mozilla/ipc/BackgroundParent.h"
|
#include "mozilla/ipc/BackgroundParent.h"
|
||||||
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
|
|
||||||
|
@ -73,30 +74,5 @@ BroadcastChannelParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
BroadcastChannelParent::Deliver(const ClonedMessageData& aData)
|
|
||||||
{
|
|
||||||
AssertIsOnBackgroundThread();
|
|
||||||
|
|
||||||
// Duplicate the data for this parent.
|
|
||||||
ClonedMessageData newData(aData);
|
|
||||||
|
|
||||||
// Create new BlobParent objects for this message.
|
|
||||||
for (uint32_t i = 0, len = newData.blobsParent().Length(); i < len; ++i) {
|
|
||||||
RefPtr<BlobImpl> impl =
|
|
||||||
static_cast<BlobParent*>(newData.blobsParent()[i])->GetBlobImpl();
|
|
||||||
|
|
||||||
PBlobParent* blobParent =
|
|
||||||
BackgroundParent::GetOrCreateActorForBlobImpl(Manager(), impl);
|
|
||||||
if (!blobParent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newData.blobsParent()[i] = blobParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
Unused << SendNotify(newData);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -26,9 +26,6 @@ class BroadcastChannelParent final : public PBroadcastChannelParent
|
||||||
|
|
||||||
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
||||||
|
|
||||||
public:
|
|
||||||
void Deliver(const ClonedMessageData& aData);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit BroadcastChannelParent(const nsAString& aOriginChannelKey);
|
explicit BroadcastChannelParent(const nsAString& aOriginChannelKey);
|
||||||
~BroadcastChannelParent();
|
~BroadcastChannelParent();
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "BroadcastChannelService.h"
|
#include "BroadcastChannelService.h"
|
||||||
#include "BroadcastChannelParent.h"
|
#include "BroadcastChannelParent.h"
|
||||||
#include "mozilla/dom/File.h"
|
#include "mozilla/dom/File.h"
|
||||||
#include "mozilla/dom/ipc/BlobParent.h"
|
#include "mozilla/dom/IPCBlobUtils.h"
|
||||||
#include "mozilla/ipc/BackgroundParent.h"
|
#include "mozilla/ipc/BackgroundParent.h"
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
|
@ -106,25 +106,43 @@ BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to keep the array alive for the life-time of this operation.
|
// We need to keep the array alive for the life-time of this operation.
|
||||||
nsTArray<RefPtr<BlobImpl>> blobs;
|
nsTArray<RefPtr<BlobImpl>> blobImpls;
|
||||||
if (!aData.blobsParent().IsEmpty()) {
|
if (!aData.blobs().IsEmpty()) {
|
||||||
blobs.SetCapacity(aData.blobsParent().Length());
|
blobImpls.SetCapacity(aData.blobs().Length());
|
||||||
|
|
||||||
for (uint32_t i = 0, len = aData.blobsParent().Length(); i < len; ++i) {
|
for (uint32_t i = 0, len = aData.blobs().Length(); i < len; ++i) {
|
||||||
RefPtr<BlobImpl> impl =
|
RefPtr<BlobImpl> impl = IPCBlobUtils::Deserialize(aData.blobs()[i]);
|
||||||
static_cast<BlobParent*>(aData.blobsParent()[i])->GetBlobImpl();
|
|
||||||
MOZ_ASSERT(impl);
|
MOZ_ASSERT(impl);
|
||||||
blobs.AppendElement(impl);
|
blobImpls.AppendElement(impl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For each parent actor, we notify the message.
|
||||||
for (uint32_t i = 0; i < parents->Length(); ++i) {
|
for (uint32_t i = 0; i < parents->Length(); ++i) {
|
||||||
BroadcastChannelParent* parent = parents->ElementAt(i);
|
BroadcastChannelParent* parent = parents->ElementAt(i);
|
||||||
MOZ_ASSERT(parent);
|
MOZ_ASSERT(parent);
|
||||||
|
|
||||||
if (parent != aParent) {
|
if (parent == aParent) {
|
||||||
parent->Deliver(aData);
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to have a copy of the data for this parent.
|
||||||
|
ClonedMessageData newData(aData);
|
||||||
|
MOZ_ASSERT(blobImpls.Length() == newData.blobs().Length());
|
||||||
|
|
||||||
|
if (!blobImpls.IsEmpty()) {
|
||||||
|
// Serialize Blob objects for this message.
|
||||||
|
for (uint32_t i = 0, len = blobImpls.Length(); i < len; ++i) {
|
||||||
|
nsresult rv = IPCBlobUtils::Serialize(blobImpls[i], parent->Manager(),
|
||||||
|
newData.blobs()[i]);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Unused << parent->SendNotify(newData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
include protocol PBlob;
|
include protocol PBlob;
|
||||||
include protocol PMemoryStream;
|
include protocol PMemoryStream;
|
||||||
|
|
||||||
|
include IPCBlob;
|
||||||
include IPCStream;
|
include IPCStream;
|
||||||
include ProtocolTypes;
|
include ProtocolTypes;
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ struct MessagePortIdentifier
|
||||||
struct ClonedMessageData
|
struct ClonedMessageData
|
||||||
{
|
{
|
||||||
SerializedStructuredCloneBuffer data;
|
SerializedStructuredCloneBuffer data;
|
||||||
PBlob[] blobs;
|
IPCBlob[] blobs;
|
||||||
IPCStream[] inputStreams;
|
IPCStream[] inputStreams;
|
||||||
MessagePortIdentifier[] identfiers;
|
MessagePortIdentifier[] identfiers;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,6 +20,8 @@ include protocol PChildToParentStream;
|
||||||
include protocol PParentToChildStream;
|
include protocol PParentToChildStream;
|
||||||
include protocol PFileDescriptorSet;
|
include protocol PFileDescriptorSet;
|
||||||
include DOMTypes;
|
include DOMTypes;
|
||||||
|
include IPCBlob;
|
||||||
|
include IPCStream;
|
||||||
include JavaScriptTypes;
|
include JavaScriptTypes;
|
||||||
include URIParams;
|
include URIParams;
|
||||||
include PPrintingTypes;
|
include PPrintingTypes;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "ipc/IPCMessageUtils.h"
|
#include "ipc/IPCMessageUtils.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/BlobBinding.h"
|
#include "mozilla/dom/BlobBinding.h"
|
||||||
|
#include "mozilla/dom/IPCBlobUtils.h"
|
||||||
#include "mozilla/dom/File.h"
|
#include "mozilla/dom/File.h"
|
||||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
@ -142,92 +143,9 @@ enum ManagerFlavorEnum {
|
||||||
BackgroundProtocol
|
BackgroundProtocol
|
||||||
};
|
};
|
||||||
|
|
||||||
template <ActorFlavorEnum>
|
template<typename M>
|
||||||
struct BlobTraits
|
bool
|
||||||
{ };
|
BuildClonedMessageData(M* aManager, StructuredCloneData& aData,
|
||||||
|
|
||||||
template <>
|
|
||||||
struct BlobTraits<Parent>
|
|
||||||
{
|
|
||||||
typedef mozilla::dom::BlobParent BlobType;
|
|
||||||
typedef mozilla::dom::PBlobParent ProtocolType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct BlobTraits<Child>
|
|
||||||
{
|
|
||||||
typedef mozilla::dom::BlobChild BlobType;
|
|
||||||
typedef mozilla::dom::PBlobChild ProtocolType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <ActorFlavorEnum, ManagerFlavorEnum>
|
|
||||||
struct ParentManagerTraits
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct ParentManagerTraits<Parent, ContentProtocol>
|
|
||||||
{
|
|
||||||
typedef mozilla::dom::nsIContentParent ConcreteContentManagerType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct ParentManagerTraits<Child, ContentProtocol>
|
|
||||||
{
|
|
||||||
typedef mozilla::dom::nsIContentChild ConcreteContentManagerType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct ParentManagerTraits<Parent, BackgroundProtocol>
|
|
||||||
{
|
|
||||||
typedef mozilla::ipc::PBackgroundParent ConcreteContentManagerType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct ParentManagerTraits<Child, BackgroundProtocol>
|
|
||||||
{
|
|
||||||
typedef mozilla::ipc::PBackgroundChild ConcreteContentManagerType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<ActorFlavorEnum>
|
|
||||||
struct DataBlobs
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct DataBlobs<Parent>
|
|
||||||
{
|
|
||||||
typedef BlobTraits<Parent>::ProtocolType ProtocolType;
|
|
||||||
|
|
||||||
static InfallibleTArray<ProtocolType*>& Blobs(ClonedMessageData& aData)
|
|
||||||
{
|
|
||||||
return aData.blobsParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const InfallibleTArray<ProtocolType*>& Blobs(const ClonedMessageData& aData)
|
|
||||||
{
|
|
||||||
return aData.blobsParent();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct DataBlobs<Child>
|
|
||||||
{
|
|
||||||
typedef BlobTraits<Child>::ProtocolType ProtocolType;
|
|
||||||
|
|
||||||
static InfallibleTArray<ProtocolType*>& Blobs(ClonedMessageData& aData)
|
|
||||||
{
|
|
||||||
return aData.blobsChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const InfallibleTArray<ProtocolType*>& Blobs(const ClonedMessageData& aData)
|
|
||||||
{
|
|
||||||
return aData.blobsChild();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<ActorFlavorEnum Flavor, ManagerFlavorEnum ManagerFlavor>
|
|
||||||
static bool
|
|
||||||
BuildClonedMessageData(typename ParentManagerTraits<Flavor, ManagerFlavor>::ConcreteContentManagerType* aManager,
|
|
||||||
StructuredCloneData& aData,
|
|
||||||
ClonedMessageData& aClonedData)
|
ClonedMessageData& aClonedData)
|
||||||
{
|
{
|
||||||
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
||||||
|
@ -245,23 +163,26 @@ BuildClonedMessageData(typename ParentManagerTraits<Flavor, ManagerFlavor>::Conc
|
||||||
const nsTArray<RefPtr<BlobImpl>>& blobImpls = aData.BlobImpls();
|
const nsTArray<RefPtr<BlobImpl>>& blobImpls = aData.BlobImpls();
|
||||||
|
|
||||||
if (!blobImpls.IsEmpty()) {
|
if (!blobImpls.IsEmpty()) {
|
||||||
typedef typename BlobTraits<Flavor>::BlobType BlobType;
|
if (NS_WARN_IF(!aClonedData.blobs().SetLength(blobImpls.Length(), fallible))) {
|
||||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
return false;
|
||||||
InfallibleTArray<ProtocolType*>& blobList = DataBlobs<Flavor>::Blobs(aClonedData);
|
}
|
||||||
uint32_t length = blobImpls.Length();
|
|
||||||
blobList.SetCapacity(length);
|
for (uint32_t i = 0; i < blobImpls.Length(); ++i) {
|
||||||
for (uint32_t i = 0; i < length; ++i) {
|
nsresult rv = IPCBlobUtils::Serialize(blobImpls[i], aManager,
|
||||||
BlobType* protocolActor = BlobType::GetOrCreate(aManager, blobImpls[i]);
|
aClonedData.blobs()[i]);
|
||||||
if (!protocolActor) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
blobList.AppendElement(protocolActor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsTArray<nsCOMPtr<nsIInputStream>>& inputStreams = aData.InputStreams();
|
const nsTArray<nsCOMPtr<nsIInputStream>>& inputStreams = aData.InputStreams();
|
||||||
|
|
||||||
if (!inputStreams.IsEmpty()) {
|
if (!inputStreams.IsEmpty()) {
|
||||||
|
if (NS_WARN_IF(!aData.IPCStreams().SetCapacity(inputStreams.Length(),
|
||||||
|
fallible))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
InfallibleTArray<IPCStream>& streams = aClonedData.inputStreams();
|
InfallibleTArray<IPCStream>& streams = aClonedData.inputStreams();
|
||||||
uint32_t length = inputStreams.Length();
|
uint32_t length = inputStreams.Length();
|
||||||
streams.SetCapacity(length);
|
streams.SetCapacity(length);
|
||||||
|
@ -286,7 +207,7 @@ StructuredCloneData::BuildClonedMessageDataForParent(
|
||||||
nsIContentParent* aParent,
|
nsIContentParent* aParent,
|
||||||
ClonedMessageData& aClonedData)
|
ClonedMessageData& aClonedData)
|
||||||
{
|
{
|
||||||
return BuildClonedMessageData<Parent, ContentProtocol>(aParent, *this, aClonedData);
|
return BuildClonedMessageData(aParent, *this, aClonedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -294,7 +215,7 @@ StructuredCloneData::BuildClonedMessageDataForChild(
|
||||||
nsIContentChild* aChild,
|
nsIContentChild* aChild,
|
||||||
ClonedMessageData& aClonedData)
|
ClonedMessageData& aClonedData)
|
||||||
{
|
{
|
||||||
return BuildClonedMessageData<Child, ContentProtocol>(aChild, *this, aClonedData);
|
return BuildClonedMessageData(aChild, *this, aClonedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -302,7 +223,7 @@ StructuredCloneData::BuildClonedMessageDataForBackgroundParent(
|
||||||
PBackgroundParent* aParent,
|
PBackgroundParent* aParent,
|
||||||
ClonedMessageData& aClonedData)
|
ClonedMessageData& aClonedData)
|
||||||
{
|
{
|
||||||
return BuildClonedMessageData<Parent, BackgroundProtocol>(aParent, *this, aClonedData);
|
return BuildClonedMessageData(aParent, *this, aClonedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -310,7 +231,7 @@ StructuredCloneData::BuildClonedMessageDataForBackgroundChild(
|
||||||
PBackgroundChild* aChild,
|
PBackgroundChild* aChild,
|
||||||
ClonedMessageData& aClonedData)
|
ClonedMessageData& aClonedData)
|
||||||
{
|
{
|
||||||
return BuildClonedMessageData<Child, BackgroundProtocol>(aChild, *this, aClonedData);
|
return BuildClonedMessageData(aChild, *this, aClonedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See the StructuredCloneData class block comment for the meanings of each val.
|
// See the StructuredCloneData class block comment for the meanings of each val.
|
||||||
|
@ -373,8 +294,6 @@ static void
|
||||||
UnpackClonedMessageData(typename MemoryTraits<MemoryFlavor>::ClonedMessageType& aClonedData,
|
UnpackClonedMessageData(typename MemoryTraits<MemoryFlavor>::ClonedMessageType& aClonedData,
|
||||||
StructuredCloneData& aData)
|
StructuredCloneData& aData)
|
||||||
{
|
{
|
||||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
|
||||||
const InfallibleTArray<ProtocolType*>& blobs = DataBlobs<Flavor>::Blobs(aClonedData);
|
|
||||||
const InfallibleTArray<MessagePortIdentifier>& identifiers = aClonedData.identfiers();
|
const InfallibleTArray<MessagePortIdentifier>& identifiers = aClonedData.identfiers();
|
||||||
|
|
||||||
MemoryTraits<MemoryFlavor>::ProvideBuffer(aClonedData, aData);
|
MemoryTraits<MemoryFlavor>::ProvideBuffer(aClonedData, aData);
|
||||||
|
@ -383,15 +302,12 @@ UnpackClonedMessageData(typename MemoryTraits<MemoryFlavor>::ClonedMessageType&
|
||||||
aData.PortIdentifiers().AppendElements(identifiers);
|
aData.PortIdentifiers().AppendElements(identifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nsTArray<IPCBlob>& blobs = aClonedData.blobs();
|
||||||
if (!blobs.IsEmpty()) {
|
if (!blobs.IsEmpty()) {
|
||||||
uint32_t length = blobs.Length();
|
uint32_t length = blobs.Length();
|
||||||
aData.BlobImpls().SetCapacity(length);
|
aData.BlobImpls().SetCapacity(length);
|
||||||
for (uint32_t i = 0; i < length; ++i) {
|
for (uint32_t i = 0; i < length; ++i) {
|
||||||
auto* blob =
|
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(blobs[i]);
|
||||||
static_cast<typename BlobTraits<Flavor>::BlobType*>(blobs[i]);
|
|
||||||
MOZ_ASSERT(blob);
|
|
||||||
|
|
||||||
RefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
|
||||||
MOZ_ASSERT(blobImpl);
|
MOZ_ASSERT(blobImpl);
|
||||||
|
|
||||||
aData.BlobImpls().AppendElement(blobImpl);
|
aData.BlobImpls().AppendElement(blobImpl);
|
||||||
|
|
|
@ -203,8 +203,8 @@ public:
|
||||||
|
|
||||||
// Actor-varying methods to convert the structured clone stored in this holder
|
// Actor-varying methods to convert the structured clone stored in this holder
|
||||||
// by a previous call to Write() into ClonedMessageData IPC representation.
|
// by a previous call to Write() into ClonedMessageData IPC representation.
|
||||||
// (Blobs are represented in IPC by PBlob actors, so we need the parent to be
|
// (Blobs are represented in IPC by IPCBlob actors, so we need the parent to
|
||||||
// able to create them.)
|
// be able to create them.)
|
||||||
bool BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
bool BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
||||||
ClonedMessageData& aClonedData);
|
ClonedMessageData& aClonedData);
|
||||||
bool BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
bool BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче