Bug 1706374 - Part 8: Add support for separate footers to IPC::Message, r=handyman

These will be used to serialize extra event metadata into IPC messages when
they're sent over the ports infrastructure. In the future better integration
may be used to reduce the overhead of this if necessary.

Differential Revision: https://phabricator.services.mozilla.com/D112773
This commit is contained in:
Nika Layzell 2021-06-21 21:53:09 +00:00
parent 4945c6bfd3
commit 56bc256e42
4 changed files with 52 additions and 1 deletions

View File

@ -429,6 +429,14 @@ bool Pickle::ReadBytesInto(PickleIterator* iter, void* data,
return iter->iter_.AdvanceAcrossSegments(buffers_, AlignInt(length) - length);
}
bool Pickle::IgnoreBytes(PickleIterator* iter, uint32_t length) const {
if (AlignInt(length) < length) {
return false;
}
return iter->iter_.AdvanceAcrossSegments(buffers_, AlignInt(length));
}
#ifdef MOZ_PICKLE_SENTINEL_CHECKING
MOZ_NEVER_INLINE
bool Pickle::ReadSentinel(PickleIterator* iter, uint32_t sentinel) const {
@ -448,7 +456,8 @@ bool Pickle::WriteSentinel(uint32_t sentinel) { return WriteUInt32(sentinel); }
#endif
void Pickle::EndRead(PickleIterator& iter, uint32_t ipcMsgType) const {
DCHECK(iter.iter_.Done());
// FIXME: Deal with the footer somehow...
// DCHECK(iter.iter_.Done());
if (NS_IsMainThread() && ipcMsgType != 0) {
uint32_t latencyMs =

View File

@ -122,6 +122,8 @@ class Pickle {
// Use it for reading the object sizes.
[[nodiscard]] bool ReadLength(PickleIterator* iter, int* result) const;
[[nodiscard]] bool IgnoreBytes(PickleIterator* iter, uint32_t length) const;
[[nodiscard]] bool ReadSentinel(PickleIterator* iter, uint32_t sentinel) const
#ifdef MOZ_PICKLE_SENTINEL_CHECKING
;

View File

@ -47,6 +47,7 @@ Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity,
#if defined(OS_MACOSX)
header()->cookie = 0;
#endif
header()->footer_offset = -1;
if (recordWriteLatency) {
create_time_ = mozilla::TimeStamp::Now();
}
@ -106,6 +107,39 @@ void Message::CopyFrom(const Message& other) {
#endif
}
void Message::WriteFooter(const void* data, uint32_t data_len) {
MOZ_ASSERT(header()->footer_offset < 0, "Already wrote a footer!");
// Record the start of the footer.
header()->footer_offset = header()->payload_size;
WriteBytes(data, data_len);
}
bool Message::ReadFooter(void* buffer, uint32_t buffer_len) {
MOZ_ASSERT(buffer_len == FooterSize());
if (buffer_len == 0) {
return true;
}
// FIXME: This is a really inefficient way to seek to the end of the message
// for sufficiently large messages.
PickleIterator iter(*this);
if (!IgnoreBytes(&iter, header()->footer_offset)) {
return false;
}
return ReadBytesInto(&iter, buffer, buffer_len);
}
uint32_t Message::FooterSize() const {
if (header()->footer_offset >= 0 &&
uint32_t(header()->footer_offset) < header()->payload_size) {
return header()->payload_size - header()->footer_offset;
}
return 0;
}
#if defined(OS_POSIX)
bool Message::WriteFileDescriptor(const base::FileDescriptor& descriptor) {
// We write the index of the descriptor so that we don't have to

View File

@ -275,6 +275,10 @@ class Message : public Pickle {
// We should not be sending messages that are smaller than our header size.
void AssertAsLargeAsHeader() const;
void WriteFooter(const void* data, uint32_t data_len);
[[nodiscard]] bool ReadFooter(void* buffer, uint32_t buffer_len);
uint32_t FooterSize() const;
// Used for async messages with no parameters.
static void Log(const Message* msg, std::wstring* l) {}
@ -338,6 +342,8 @@ class Message : public Pickle {
uint32_t interrupt_local_stack_depth;
// Sequence number
int32_t seqno;
// Offset of the message's footer in the payload, or -1 if invalid.
int32_t footer_offset;
};
Header* header() { return headerT<Header>(); }