зеркало из 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 "BroadcastChannelService.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/IPCStreamUtils.h"
|
||||
#include "mozilla/Unused.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 mozilla
|
||||
|
|
|
@ -26,9 +26,6 @@ class BroadcastChannelParent final : public PBroadcastChannelParent
|
|||
|
||||
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
||||
|
||||
public:
|
||||
void Deliver(const ClonedMessageData& aData);
|
||||
|
||||
private:
|
||||
explicit BroadcastChannelParent(const nsAString& aOriginChannelKey);
|
||||
~BroadcastChannelParent();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "BroadcastChannelService.h"
|
||||
#include "BroadcastChannelParent.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
|
||||
#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.
|
||||
nsTArray<RefPtr<BlobImpl>> blobs;
|
||||
if (!aData.blobsParent().IsEmpty()) {
|
||||
blobs.SetCapacity(aData.blobsParent().Length());
|
||||
nsTArray<RefPtr<BlobImpl>> blobImpls;
|
||||
if (!aData.blobs().IsEmpty()) {
|
||||
blobImpls.SetCapacity(aData.blobs().Length());
|
||||
|
||||
for (uint32_t i = 0, len = aData.blobsParent().Length(); i < len; ++i) {
|
||||
RefPtr<BlobImpl> impl =
|
||||
static_cast<BlobParent*>(aData.blobsParent()[i])->GetBlobImpl();
|
||||
MOZ_ASSERT(impl);
|
||||
blobs.AppendElement(impl);
|
||||
for (uint32_t i = 0, len = aData.blobs().Length(); i < len; ++i) {
|
||||
RefPtr<BlobImpl> impl = IPCBlobUtils::Deserialize(aData.blobs()[i]);
|
||||
|
||||
MOZ_ASSERT(impl);
|
||||
blobImpls.AppendElement(impl);
|
||||
}
|
||||
}
|
||||
|
||||
// For each parent actor, we notify the message.
|
||||
for (uint32_t i = 0; i < parents->Length(); ++i) {
|
||||
BroadcastChannelParent* parent = parents->ElementAt(i);
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent != aParent) {
|
||||
parent->Deliver(aData);
|
||||
if (parent == aParent) {
|
||||
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 PMemoryStream;
|
||||
|
||||
include IPCBlob;
|
||||
include IPCStream;
|
||||
include ProtocolTypes;
|
||||
|
||||
|
@ -41,7 +42,7 @@ struct MessagePortIdentifier
|
|||
struct ClonedMessageData
|
||||
{
|
||||
SerializedStructuredCloneBuffer data;
|
||||
PBlob[] blobs;
|
||||
IPCBlob[] blobs;
|
||||
IPCStream[] inputStreams;
|
||||
MessagePortIdentifier[] identfiers;
|
||||
};
|
||||
|
|
|
@ -20,6 +20,8 @@ include protocol PChildToParentStream;
|
|||
include protocol PParentToChildStream;
|
||||
include protocol PFileDescriptorSet;
|
||||
include DOMTypes;
|
||||
include IPCBlob;
|
||||
include IPCStream;
|
||||
include JavaScriptTypes;
|
||||
include URIParams;
|
||||
include PPrintingTypes;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -142,92 +143,9 @@ enum ManagerFlavorEnum {
|
|||
BackgroundProtocol
|
||||
};
|
||||
|
||||
template <ActorFlavorEnum>
|
||||
struct BlobTraits
|
||||
{ };
|
||||
|
||||
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,
|
||||
template<typename M>
|
||||
bool
|
||||
BuildClonedMessageData(M* aManager, StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
||||
|
@ -245,23 +163,26 @@ BuildClonedMessageData(typename ParentManagerTraits<Flavor, ManagerFlavor>::Conc
|
|||
const nsTArray<RefPtr<BlobImpl>>& blobImpls = aData.BlobImpls();
|
||||
|
||||
if (!blobImpls.IsEmpty()) {
|
||||
typedef typename BlobTraits<Flavor>::BlobType BlobType;
|
||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
||||
InfallibleTArray<ProtocolType*>& blobList = DataBlobs<Flavor>::Blobs(aClonedData);
|
||||
uint32_t length = blobImpls.Length();
|
||||
blobList.SetCapacity(length);
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
BlobType* protocolActor = BlobType::GetOrCreate(aManager, blobImpls[i]);
|
||||
if (!protocolActor) {
|
||||
if (NS_WARN_IF(!aClonedData.blobs().SetLength(blobImpls.Length(), fallible))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < blobImpls.Length(); ++i) {
|
||||
nsresult rv = IPCBlobUtils::Serialize(blobImpls[i], aManager,
|
||||
aClonedData.blobs()[i]);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
blobList.AppendElement(protocolActor);
|
||||
}
|
||||
}
|
||||
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& inputStreams = aData.InputStreams();
|
||||
|
||||
if (!inputStreams.IsEmpty()) {
|
||||
if (NS_WARN_IF(!aData.IPCStreams().SetCapacity(inputStreams.Length(),
|
||||
fallible))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
InfallibleTArray<IPCStream>& streams = aClonedData.inputStreams();
|
||||
uint32_t length = inputStreams.Length();
|
||||
streams.SetCapacity(length);
|
||||
|
@ -286,7 +207,7 @@ StructuredCloneData::BuildClonedMessageDataForParent(
|
|||
nsIContentParent* aParent,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
return BuildClonedMessageData<Parent, ContentProtocol>(aParent, *this, aClonedData);
|
||||
return BuildClonedMessageData(aParent, *this, aClonedData);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -294,7 +215,7 @@ StructuredCloneData::BuildClonedMessageDataForChild(
|
|||
nsIContentChild* aChild,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
return BuildClonedMessageData<Child, ContentProtocol>(aChild, *this, aClonedData);
|
||||
return BuildClonedMessageData(aChild, *this, aClonedData);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -302,7 +223,7 @@ StructuredCloneData::BuildClonedMessageDataForBackgroundParent(
|
|||
PBackgroundParent* aParent,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
return BuildClonedMessageData<Parent, BackgroundProtocol>(aParent, *this, aClonedData);
|
||||
return BuildClonedMessageData(aParent, *this, aClonedData);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -310,7 +231,7 @@ StructuredCloneData::BuildClonedMessageDataForBackgroundChild(
|
|||
PBackgroundChild* aChild,
|
||||
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.
|
||||
|
@ -373,8 +294,6 @@ static void
|
|||
UnpackClonedMessageData(typename MemoryTraits<MemoryFlavor>::ClonedMessageType& aClonedData,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
||||
const InfallibleTArray<ProtocolType*>& blobs = DataBlobs<Flavor>::Blobs(aClonedData);
|
||||
const InfallibleTArray<MessagePortIdentifier>& identifiers = aClonedData.identfiers();
|
||||
|
||||
MemoryTraits<MemoryFlavor>::ProvideBuffer(aClonedData, aData);
|
||||
|
@ -383,15 +302,12 @@ UnpackClonedMessageData(typename MemoryTraits<MemoryFlavor>::ClonedMessageType&
|
|||
aData.PortIdentifiers().AppendElements(identifiers);
|
||||
}
|
||||
|
||||
const nsTArray<IPCBlob>& blobs = aClonedData.blobs();
|
||||
if (!blobs.IsEmpty()) {
|
||||
uint32_t length = blobs.Length();
|
||||
aData.BlobImpls().SetCapacity(length);
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
auto* blob =
|
||||
static_cast<typename BlobTraits<Flavor>::BlobType*>(blobs[i]);
|
||||
MOZ_ASSERT(blob);
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
||||
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(blobs[i]);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
aData.BlobImpls().AppendElement(blobImpl);
|
||||
|
|
|
@ -203,8 +203,8 @@ public:
|
|||
|
||||
// Actor-varying methods to convert the structured clone stored in this holder
|
||||
// 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
|
||||
// able to create them.)
|
||||
// (Blobs are represented in IPC by IPCBlob actors, so we need the parent to
|
||||
// be able to create them.)
|
||||
bool BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
||||
ClonedMessageData& aClonedData);
|
||||
bool BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
||||
|
|
Загрузка…
Ссылка в новой задаче