зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c5b0781d9f
Коммит
a7fa32643f
|
@ -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)
|
||||
|
||||
//
|
||||
|
|
Загрузка…
Ссылка в новой задаче