Bug 1605566 - MessagePort + wasm - part 3 - MessagePort serializes objects using MessageData union, r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D59614

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrea Marchesini 2020-01-15 10:01:11 +00:00
Родитель c5b0781d9f
Коммит a7fa32643f
13 изменённых файлов: 116 добавлений и 56 удалений

Просмотреть файл

@ -47,6 +47,19 @@ StructuredCloneData::StructuredCloneData(
mExternalData(JS::StructuredCloneScope::DifferentProcess),
mInitialized(false) {}
StructuredCloneData::StructuredCloneData(
StructuredCloneHolder::StructuredCloneScope aScope)
: StructuredCloneHolder(StructuredCloneHolder::CloningSupported,
StructuredCloneHolder::TransferringSupported,
aScope),
mExternalData(JS::StructuredCloneScope::DifferentProcess),
mInitialized(false) {
MOZ_ASSERT(
aScope == StructuredCloneHolder::StructuredCloneScope::DifferentProcess ||
aScope ==
StructuredCloneHolder::StructuredCloneScope::UnknownDestination);
}
StructuredCloneData::~StructuredCloneData() {}
StructuredCloneData& StructuredCloneData::operator=(

Просмотреть файл

@ -149,6 +149,9 @@ class StructuredCloneData : public StructuredCloneHolder {
StructuredCloneData(StructuredCloneData&& aOther);
// Only DifferentProcess and UnknownDestination scopes are supported.
explicit StructuredCloneData(StructuredCloneScope aScope);
~StructuredCloneData();
StructuredCloneData& operator=(const StructuredCloneData& aOther) = delete;

Просмотреть файл

@ -387,7 +387,7 @@ void MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
AutoTArray<RefPtr<SharedMessagePortMessage>, 1> array;
array.AppendElement(data);
AutoTArray<ClonedMessageData, 1> messages;
AutoTArray<MessageData, 1> messages;
// note: `messages` will borrow the underlying buffer, but this is okay
// because reverse destruction order means `messages` will be destroyed prior
// to `array`/`data`.
@ -553,7 +553,7 @@ void MessagePort::SetOnmessage(EventHandlerNonNull* aCallback) {
// another actor. It receives a list of messages to be dispatch. It can be that
// we were waiting for this entangling step in order to disentangle the port or
// to close it.
void MessagePort::Entangled(nsTArray<ClonedMessageData>& aMessages) {
void MessagePort::Entangled(nsTArray<MessageData>& aMessages) {
MOZ_ASSERT(mState == eStateEntangling ||
mState == eStateEntanglingForDisentangle ||
mState == eStateEntanglingForClose);
@ -564,7 +564,7 @@ void MessagePort::Entangled(nsTArray<ClonedMessageData>& aMessages) {
// If we have pending messages, these have to be sent.
if (!mMessagesForTheOtherPort.IsEmpty()) {
{
nsTArray<ClonedMessageData> messages;
nsTArray<MessageData> messages;
SharedMessagePortMessage::FromSharedToMessagesChild(
mActor, mMessagesForTheOtherPort, messages);
mActor->SendPostMessages(messages);
@ -614,7 +614,7 @@ void MessagePort::StartDisentangling() {
mActor->SendStopSendingData();
}
void MessagePort::MessagesReceived(nsTArray<ClonedMessageData>& aMessages) {
void MessagePort::MessagesReceived(nsTArray<MessageData>& aMessages) {
MOZ_ASSERT(mState == eStateEntangled || mState == eStateDisentangling ||
// This last step can happen only if Close() has been called
// manually. At this point SendClose() is sent but we can still
@ -652,13 +652,13 @@ void MessagePort::Disentangle() {
mState = eStateDisentangled;
{
nsTArray<ClonedMessageData> messages;
nsTArray<MessageData> messages;
SharedMessagePortMessage::FromSharedToMessagesChild(mActor, mMessages,
messages);
mActor->SendDisentangle(messages);
}
// Only clear mMessages after the ClonedMessageData instances have gone out of
// scope because they borrow mMessages' underlying JSStructuredCloneDatas.
// Only clear mMessages after the MessageData instances have gone out of scope
// because they borrow mMessages' underlying JSStructuredCloneDatas.
mMessages.Clear();
mActor->SetPort(nullptr);

Просмотреть файл

@ -22,6 +22,7 @@ class nsIGlobalObject;
namespace mozilla {
namespace dom {
class MessageData;
class MessagePortChild;
struct PostMessageOptions;
class PostMessageRunnable;
@ -118,8 +119,8 @@ class MessagePort final : public DOMEventTargetHelper {
// These methods are useful for MessagePortChild
void Entangled(nsTArray<ClonedMessageData>& aMessages);
void MessagesReceived(nsTArray<ClonedMessageData>& aMessages);
void Entangled(nsTArray<MessageData>& aMessages);
void MessagesReceived(nsTArray<MessageData>& aMessages);
void StopSendingDataConfirmed();
void Closed();

Просмотреть файл

@ -22,7 +22,7 @@ mozilla::ipc::IPCResult MessagePortChild::RecvStopSendingDataConfirmed() {
}
mozilla::ipc::IPCResult MessagePortChild::RecvEntangled(
nsTArray<ClonedMessageData>&& aMessages) {
nsTArray<MessageData>&& aMessages) {
if (mPort) {
mPort->Entangled(aMessages);
}
@ -30,7 +30,7 @@ mozilla::ipc::IPCResult MessagePortChild::RecvEntangled(
}
mozilla::ipc::IPCResult MessagePortChild::RecvReceiveData(
nsTArray<ClonedMessageData>&& aMessages) {
nsTArray<MessageData>&& aMessages) {
if (mPort) {
mPort->MessagesReceived(aMessages);
}

Просмотреть файл

@ -29,11 +29,9 @@ class MessagePortChild final : public PMessagePortChild {
private:
~MessagePortChild() { MOZ_ASSERT(!mPort); }
mozilla::ipc::IPCResult RecvEntangled(
nsTArray<ClonedMessageData>&& aMessages);
mozilla::ipc::IPCResult RecvEntangled(nsTArray<MessageData>&& aMessages);
mozilla::ipc::IPCResult RecvReceiveData(
nsTArray<ClonedMessageData>&& aMessages);
mozilla::ipc::IPCResult RecvReceiveData(nsTArray<MessageData>&& aMessages);
mozilla::ipc::IPCResult RecvStopSendingDataConfirmed();

Просмотреть файл

@ -38,7 +38,7 @@ bool MessagePortParent::Entangle(const nsID& aDestinationUUID,
}
mozilla::ipc::IPCResult MessagePortParent::RecvPostMessages(
nsTArray<ClonedMessageData>&& aMessages) {
nsTArray<MessageData>&& aMessages) {
// This converts the object in a data struct where we have BlobImpls.
FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
if (NS_WARN_IF(!SharedMessagePortMessage::FromMessagesToSharedParent(
@ -66,7 +66,7 @@ mozilla::ipc::IPCResult MessagePortParent::RecvPostMessages(
}
mozilla::ipc::IPCResult MessagePortParent::RecvDisentangle(
nsTArray<ClonedMessageData>&& aMessages) {
nsTArray<MessageData>&& aMessages) {
// This converts the object in a data struct where we have BlobImpls.
FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
if (NS_WARN_IF(!SharedMessagePortMessage::FromMessagesToSharedParent(
@ -127,8 +127,7 @@ void MessagePortParent::ActorDestroy(ActorDestroyReason aWhy) {
}
}
bool MessagePortParent::Entangled(
const nsTArray<ClonedMessageData>& aMessages) {
bool MessagePortParent::Entangled(const nsTArray<MessageData>& aMessages) {
MOZ_ASSERT(!mEntangled);
mEntangled = true;
return SendEntangled(aMessages);

Просмотреть файл

@ -26,7 +26,7 @@ class MessagePortParent final
bool Entangle(const nsID& aDestinationUUID, const uint32_t& aSequenceID);
bool Entangled(const nsTArray<ClonedMessageData>& aMessages);
bool Entangled(const nsTArray<MessageData>& aMessages);
void Close();
void CloseAndDelete();
@ -39,11 +39,9 @@ class MessagePortParent final
const uint32_t& aSequenceID);
private:
mozilla::ipc::IPCResult RecvPostMessages(
nsTArray<ClonedMessageData>&& aMessages);
mozilla::ipc::IPCResult RecvPostMessages(nsTArray<MessageData>&& aMessages);
mozilla::ipc::IPCResult RecvDisentangle(
nsTArray<ClonedMessageData>&& aMessages);
mozilla::ipc::IPCResult RecvDisentangle(nsTArray<MessageData>&& aMessages);
mozilla::ipc::IPCResult RecvStopSendingData();

Просмотреть файл

@ -148,7 +148,7 @@ bool MessagePortService::RequestEntangling(MessagePortParent* aParent,
// that reverse destruction order works for us.
FallibleTArray<RefPtr<SharedMessagePortMessage>> messages(
std::move(data->mMessages));
FallibleTArray<ClonedMessageData> array;
FallibleTArray<MessageData> array;
if (!SharedMessagePortMessage::FromSharedToMessagesParent(aParent, messages,
array)) {
CloseAll(aParent->ID());
@ -231,7 +231,7 @@ bool MessagePortService::DisentanglePort(
data->mParent = nextParent;
data->mNextParents.RemoveElementAt(index);
FallibleTArray<ClonedMessageData> array;
FallibleTArray<MessageData> array;
if (!SharedMessagePortMessage::FromSharedToMessagesParent(data->mParent,
aMessages, array)) {
return false;
@ -348,7 +348,7 @@ bool MessagePortService::PostMessages(
// If the parent can send data to the child, let's proceed.
if (data->mParent && data->mParent->CanSendData()) {
{
FallibleTArray<ClonedMessageData> messages;
FallibleTArray<MessageData> messages;
if (!SharedMessagePortMessage::FromSharedToMessagesParent(
data->mParent, data->mMessages, messages)) {
return false;

Просмотреть файл

@ -9,6 +9,7 @@ include protocol PIPCBlobInputStream; // FIXME: bug 792908
include protocol PParentToChildStream; // FIXME: bug 792908
include DOMTypes;
include ProtocolTypes;
using struct mozilla::SerializedStructuredCloneBuffer
from "ipc/IPCMessageUtils.h";
@ -16,6 +17,15 @@ using struct mozilla::SerializedStructuredCloneBuffer
namespace mozilla {
namespace dom {
struct RefMessageData {
nsID uuid;
};
union MessageData {
ClonedMessageData;
RefMessageData;
};
// This protocol is used for the MessageChannel/MessagePort API
protocol PMessagePort
{
@ -35,14 +45,14 @@ protocol PMessagePort
4. Recv__delete__(); */
parent:
async PostMessages(ClonedMessageData[] messages);
async Disentangle(ClonedMessageData[] messages);
async PostMessages(MessageData[] messages);
async Disentangle(MessageData[] messages);
async StopSendingData();
async Close();
child:
async Entangled(ClonedMessageData[] messages);
async ReceiveData(ClonedMessageData[] messages);
async Entangled(MessageData[] messages);
async ReceiveData(MessageData[] messages);
async StopSendingDataConfirmed();
async __delete__();

Просмотреть файл

@ -23,7 +23,7 @@ namespace dom {
void SharedMessagePortMessage::FromSharedToMessagesChild(
MessagePortChild* aActor,
const nsTArray<RefPtr<SharedMessagePortMessage>>& aData,
nsTArray<ClonedMessageData>& aArray) {
nsTArray<MessageData>& aArray) {
MOZ_ASSERT(aActor);
MOZ_ASSERT(aArray.IsEmpty());
aArray.SetCapacity(aData.Length());
@ -32,14 +32,26 @@ void SharedMessagePortMessage::FromSharedToMessagesChild(
MOZ_ASSERT(backgroundManager);
for (auto& data : aData) {
ClonedMessageData* message = aArray.AppendElement();
data->BuildClonedMessageDataForBackgroundChild(backgroundManager, *message);
MessageData* message = aArray.AppendElement();
if (data->CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::DifferentProcess) {
ClonedMessageData clonedData;
data->BuildClonedMessageDataForBackgroundChild(backgroundManager,
clonedData);
*message = clonedData;
continue;
}
MOZ_ASSERT(data->CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::SameProcess);
*message = RefMessageData(); // TODO
}
}
/* static */
bool SharedMessagePortMessage::FromMessagesToSharedChild(
nsTArray<ClonedMessageData>& aArray,
nsTArray<MessageData>& aArray,
FallibleTArray<RefPtr<SharedMessagePortMessage>>& aData) {
MOZ_ASSERT(aData.IsEmpty());
@ -49,7 +61,13 @@ bool SharedMessagePortMessage::FromMessagesToSharedChild(
for (auto& message : aArray) {
RefPtr<SharedMessagePortMessage> data = new SharedMessagePortMessage();
if (message.type() == MessageData::TClonedMessageData) {
data->StealFromClonedMessageDataForBackgroundChild(message);
} else {
MOZ_ASSERT(message.type() == MessageData::TRefMessageData);
// TODO
}
if (!aData.AppendElement(data, mozilla::fallible)) {
return false;
@ -63,7 +81,7 @@ bool SharedMessagePortMessage::FromMessagesToSharedChild(
bool SharedMessagePortMessage::FromSharedToMessagesParent(
MessagePortParent* aActor,
const nsTArray<RefPtr<SharedMessagePortMessage>>& aData,
FallibleTArray<ClonedMessageData>& aArray) {
FallibleTArray<MessageData>& aArray) {
MOZ_ASSERT(aArray.IsEmpty());
if (NS_WARN_IF(!aArray.SetCapacity(aData.Length(), mozilla::fallible))) {
@ -74,9 +92,20 @@ bool SharedMessagePortMessage::FromSharedToMessagesParent(
MOZ_ASSERT(backgroundManager);
for (auto& data : aData) {
ClonedMessageData* message = aArray.AppendElement(mozilla::fallible);
MessageData* message = aArray.AppendElement(mozilla::fallible);
if (data->CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::DifferentProcess) {
ClonedMessageData clonedData;
data->BuildClonedMessageDataForBackgroundParent(backgroundManager,
*message);
clonedData);
*message = clonedData;
continue;
}
MOZ_ASSERT(data->CloneScope() ==
StructuredCloneHolder::StructuredCloneScope::SameProcess);
*message = RefMessageData(); // TODO
}
return true;
@ -84,7 +113,7 @@ bool SharedMessagePortMessage::FromSharedToMessagesParent(
/* static */
bool SharedMessagePortMessage::FromMessagesToSharedParent(
nsTArray<ClonedMessageData>& aArray,
nsTArray<MessageData>& aArray,
FallibleTArray<RefPtr<SharedMessagePortMessage>>& aData) {
MOZ_ASSERT(aData.IsEmpty());
@ -94,7 +123,13 @@ bool SharedMessagePortMessage::FromMessagesToSharedParent(
for (auto& message : aArray) {
RefPtr<SharedMessagePortMessage> data = new SharedMessagePortMessage();
if (message.type() == MessageData::TClonedMessageData) {
data->StealFromClonedMessageDataForBackgroundParent(message);
} else {
MOZ_ASSERT(message.type() == MessageData::TRefMessageData);
// TODO
}
if (!aData.AppendElement(data, mozilla::fallible)) {
return false;

Просмотреть файл

@ -20,36 +20,37 @@ class SharedMessagePortMessage final : public ipc::StructuredCloneData {
public:
NS_INLINE_DECL_REFCOUNTING(SharedMessagePortMessage)
SharedMessagePortMessage() : ipc::StructuredCloneData() {}
SharedMessagePortMessage()
: ipc::StructuredCloneData(StructuredCloneScope::UnknownDestination) {}
// Note that the populated ClonedMessageData borrows the underlying
// Note that the populated MessageData borrows the underlying
// JSStructuredCloneData from the SharedMessagePortMessage, so the caller is
// required to ensure that the ClonedMessageData instances are destroyed prior
// to the SharedMessagePortMessage instances.
// required to ensure that the MessageData instances are destroyed prior to
// the SharedMessagePortMessage instances.
static void FromSharedToMessagesChild(
MessagePortChild* aActor,
const nsTArray<RefPtr<SharedMessagePortMessage>>& aData,
nsTArray<ClonedMessageData>& aArray);
nsTArray<MessageData>& aArray);
static bool FromMessagesToSharedChild(
nsTArray<ClonedMessageData>& aArray,
nsTArray<MessageData>& aArray,
FallibleTArray<RefPtr<SharedMessagePortMessage>>& aData);
// Note that the populated ClonedMessageData borrows the underlying
// Note that the populated MessageData borrows the underlying
// JSStructuredCloneData from the SharedMessagePortMessage, so the caller is
// required to ensure that the ClonedMessageData instances are destroyed prior
// to the SharedMessagePortMessage instances.
// required to ensure that the MessageData instances are destroyed prior to
// the SharedMessagePortMessage instances.
static bool FromSharedToMessagesParent(
MessagePortParent* aActor,
const nsTArray<RefPtr<SharedMessagePortMessage>>& aData,
FallibleTArray<ClonedMessageData>& aArray);
FallibleTArray<MessageData>& aArray);
static bool FromMessagesToSharedParent(
nsTArray<ClonedMessageData>& aArray,
nsTArray<MessageData>& aArray,
FallibleTArray<RefPtr<SharedMessagePortMessage>>& aData);
private:
~SharedMessagePortMessage() {}
~SharedMessagePortMessage() = default;
};
} // namespace dom

Просмотреть файл

@ -69,7 +69,8 @@ class StructuredCloneData;
namespace mozilla {
namespace dom {
class ClonedMessageData;
class MessagePortMessage;
class MessageData;
class RefMessageData;
namespace indexedDB {
struct StructuredCloneReadInfo;
class SerializedStructuredCloneReadInfo;
@ -731,7 +732,8 @@ DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::IndexCursorResponse)
DECLARE_USE_COPY_CONSTRUCTORS(
mozilla::dom::indexedDB::SerializedStructuredCloneReadInfo);
DECLARE_USE_COPY_CONSTRUCTORS(JSStructuredCloneData)
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessagePortMessage)
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessageData)
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::RefMessageData)
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::SourceBufferTask)
//