Bug 1966936 - Switch various IPC IDs to 64-bits, r=ipc-reviewers,mccr8,jld a=RyanVM

This changes a few IDs which have historically been 32-bit integers to
instead be 64-bit integers, reducing the chance of the value
overflowing.

Differential Revision: https://phabricator.services.mozilla.com/D250502
This commit is contained in:
Nika Layzell
2025-05-29 19:22:10 +00:00
committed by rvandermeulen@mozilla.com
parent 2b681a7411
commit 31a3ea2fb1
34 changed files with 346 additions and 362 deletions

14
dom/cache/Manager.cpp vendored
View File

@@ -370,14 +370,16 @@ class Manager::Factory {
} }
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
static void RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId) { static void RecordMayNotDeleteCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
if (sFactory) { if (sFactory) {
sFactory->mPotentiallyUnreleasedCSCP.AppendElement( sFactory->mPotentiallyUnreleasedCSCP.AppendElement(
aCacheStreamControlParentId); aCacheStreamControlParentId);
} }
} }
static void RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId) { static void RecordHaveDeletedCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
if (sFactory) { if (sFactory) {
sFactory->mPotentiallyUnreleasedCSCP.RemoveElement( sFactory->mPotentiallyUnreleasedCSCP.RemoveElement(
aCacheStreamControlParentId); aCacheStreamControlParentId);
@@ -519,7 +521,7 @@ class Manager::Factory {
// trigger the deletion of the factory while still executing this loop. // trigger the deletion of the factory while still executing this loop.
bool mInSyncAbortOrShutdown; bool mInSyncAbortOrShutdown;
nsTArray<int32_t> mPotentiallyUnreleasedCSCP; nsTArray<mozilla::ipc::ActorId> mPotentiallyUnreleasedCSCP;
}; };
// static // static
@@ -1691,11 +1693,13 @@ bool Manager::IsShutdownAllComplete() {
} }
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
void Manager::RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId) { void Manager::RecordMayNotDeleteCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
Factory::RecordMayNotDeleteCSCP(aCacheStreamControlParentId); Factory::RecordMayNotDeleteCSCP(aCacheStreamControlParentId);
} }
void Manager::RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId) { void Manager::RecordHaveDeletedCSCP(
mozilla::ipc::ActorId aCacheStreamControlParentId) {
Factory::RecordHaveDeletedCSCP(aCacheStreamControlParentId); Factory::RecordHaveDeletedCSCP(aCacheStreamControlParentId);
} }
#endif #endif

5
dom/cache/Manager.h vendored
View File

@@ -199,8 +199,9 @@ class Manager final : public SafeRefCounted<Manager>, public Stringifyable {
nsCOMPtr<nsIInputStream>&& aBodyStream); nsCOMPtr<nsIInputStream>&& aBodyStream);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
void RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId); void RecordMayNotDeleteCSCP(
void RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId); mozilla::ipc::ActorId aCacheStreamControlParentId);
void RecordHaveDeletedCSCP(mozilla::ipc::ActorId aCacheStreamControlParentId);
#endif #endif
private: private:

View File

@@ -227,7 +227,7 @@ void OffscreenCanvas::GetContext(
return; return;
} }
Maybe<int32_t> childId; Maybe<mozilla::ipc::ActorId> childId;
MOZ_ASSERT(mCurrentContext); MOZ_ASSERT(mCurrentContext);
switch (mCurrentContextType) { switch (mCurrentContextType) {

View File

@@ -90,7 +90,7 @@ RefPtr<layers::ImageContainer> OffscreenCanvasDisplayHelper::GetImageContainer()
void OffscreenCanvasDisplayHelper::UpdateContext( void OffscreenCanvasDisplayHelper::UpdateContext(
OffscreenCanvas* aOffscreenCanvas, RefPtr<ThreadSafeWorkerRef>&& aWorkerRef, OffscreenCanvas* aOffscreenCanvas, RefPtr<ThreadSafeWorkerRef>&& aWorkerRef,
CanvasContextType aType, const Maybe<int32_t>& aChildId) { CanvasContextType aType, const Maybe<mozilla::ipc::ActorId>& aChildId) {
RefPtr<layers::ImageContainer> imageContainer = RefPtr<layers::ImageContainer> imageContainer =
MakeRefPtr<layers::ImageContainer>( MakeRefPtr<layers::ImageContainer>(
layers::ImageUsageType::OffscreenCanvas, layers::ImageUsageType::OffscreenCanvas,

View File

@@ -11,6 +11,7 @@
#include "GLContextTypes.h" #include "GLContextTypes.h"
#include "mozilla/dom/CanvasRenderingContextHelper.h" #include "mozilla/dom/CanvasRenderingContextHelper.h"
#include "mozilla/gfx/Point.h" #include "mozilla/gfx/Point.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/LayersTypes.h" #include "mozilla/layers/LayersTypes.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/Mutex.h" #include "mozilla/Mutex.h"
@@ -45,7 +46,8 @@ class OffscreenCanvasDisplayHelper final {
void UpdateContext(OffscreenCanvas* aOffscreenCanvas, void UpdateContext(OffscreenCanvas* aOffscreenCanvas,
RefPtr<ThreadSafeWorkerRef>&& aWorkerRef, RefPtr<ThreadSafeWorkerRef>&& aWorkerRef,
CanvasContextType aType, const Maybe<int32_t>& aChildId); CanvasContextType aType,
const Maybe<mozilla::ipc::ActorId>& aChildId);
void FlushForDisplay(); void FlushForDisplay();
@@ -83,7 +85,7 @@ class OffscreenCanvasDisplayHelper final {
OffscreenCanvasDisplayData mData MOZ_GUARDED_BY(mMutex); OffscreenCanvasDisplayData mData MOZ_GUARDED_BY(mMutex);
CanvasContextType mType MOZ_GUARDED_BY(mMutex) = CanvasContextType::NoContext; CanvasContextType mType MOZ_GUARDED_BY(mMutex) = CanvasContextType::NoContext;
Maybe<uint32_t> mContextManagerId MOZ_GUARDED_BY(mMutex); Maybe<uint32_t> mContextManagerId MOZ_GUARDED_BY(mMutex);
Maybe<int32_t> mContextChildId MOZ_GUARDED_BY(mMutex); Maybe<mozilla::ipc::ActorId> mContextChildId MOZ_GUARDED_BY(mMutex);
const mozilla::layers::ImageContainer::ProducerID mImageProducerID; const mozilla::layers::ImageContainer::ProducerID mImageProducerID;
mozilla::layers::ImageContainer::FrameID mLastFrameID MOZ_GUARDED_BY(mMutex) = mozilla::layers::ImageContainer::FrameID mLastFrameID MOZ_GUARDED_BY(mMutex) =
0; 0;

View File

@@ -1032,7 +1032,7 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
// process as the WebGL canvas. Query it for the surface. // process as the WebGL canvas. Query it for the surface.
const auto& sdc = sd.get_SurfaceDescriptorCanvasSurface(); const auto& sdc = sd.get_SurfaceDescriptorCanvasSurface();
uint32_t managerId = sdc.managerId(); uint32_t managerId = sdc.managerId();
int32_t canvasId = sdc.canvasId(); mozilla::ipc::ActorId canvasId = sdc.canvasId();
uintptr_t surfaceId = sdc.surfaceId(); uintptr_t surfaceId = sdc.surfaceId();
surf = gfx::CanvasManagerParent::GetCanvasSurface( surf = gfx::CanvasManagerParent::GetCanvasSurface(
webgl->GetContentId(), managerId, canvasId, surfaceId); webgl->GetContentId(), managerId, canvasId, surfaceId);

View File

@@ -159,10 +159,12 @@ GetStatsPromiseForThisProcess(const nsAString& aPcIdFilter) {
std::move(UnwrapUniquePtrs)); std::move(UnwrapUniquePtrs));
} }
static std::map<int32_t, dom::Sequence<nsString>>& GetWebrtcGlobalLogStash() { static std::map<mozilla::ipc::ActorId, dom::Sequence<nsString>>&
static StaticAutoPtr<std::map<int32_t, dom::Sequence<nsString>>> sStash; GetWebrtcGlobalLogStash() {
static StaticAutoPtr<std::map<mozilla::ipc::ActorId, dom::Sequence<nsString>>>
sStash;
if (!sStash) { if (!sStash) {
sStash = new std::map<int32_t, dom::Sequence<nsString>>(); sStash = new std::map<mozilla::ipc::ActorId, dom::Sequence<nsString>>();
ClearOnShutdown(&sStash); ClearOnShutdown(&sStash);
} }
return *sStash; return *sStash;

View File

@@ -229,7 +229,7 @@ layers::ActiveResourceTracker* CanvasManagerChild::GetActiveResourceTracker() {
} }
already_AddRefed<DataSourceSurface> CanvasManagerChild::GetSnapshot( already_AddRefed<DataSourceSurface> CanvasManagerChild::GetSnapshot(
uint32_t aManagerId, int32_t aProtocolId, uint32_t aManagerId, ActorId aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId, const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId, SurfaceFormat aFormat, const Maybe<RawId>& aCommandEncoderId, SurfaceFormat aFormat,
bool aPremultiply, bool aYFlip) { bool aPremultiply, bool aYFlip) {

View File

@@ -38,7 +38,7 @@ class CanvasManagerChild final : public PCanvasManagerChild {
uint32_t aId); uint32_t aId);
uint32_t Id() const { return mId; } uint32_t Id() const { return mId; }
already_AddRefed<DataSourceSurface> GetSnapshot( already_AddRefed<DataSourceSurface> GetSnapshot(
uint32_t aManagerId, int32_t aProtocolId, uint32_t aManagerId, ActorId aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId, const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId, SurfaceFormat aFormat, const Maybe<RawId>& aCommandEncoderId, SurfaceFormat aFormat,
bool aPremultiply, bool aYFlip); bool aPremultiply, bool aYFlip);

View File

@@ -178,7 +178,7 @@ CanvasManagerParent::AllocPCanvasParent() {
} }
mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot( mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
const uint32_t& aManagerId, const int32_t& aProtocolId, const uint32_t& aManagerId, const ActorId& aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId, const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId, const Maybe<RawId>& aCommandEncoderId,
webgl::FrontBufferSnapshotIpc* aResult) { webgl::FrontBufferSnapshotIpc* aResult) {
@@ -240,7 +240,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
} }
/* static */ mozilla::ipc::IProtocol* CanvasManagerParent::GetCanvasActor( /* static */ mozilla::ipc::IProtocol* CanvasManagerParent::GetCanvasActor(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId) { dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId) {
IProtocol* actor = nullptr; IProtocol* actor = nullptr;
for (CanvasManagerParent* i : sManagers) { for (CanvasManagerParent* i : sManagers) {
if (i->mContentId == aContentId && i->mId == aManagerId) { if (i->mContentId == aContentId && i->mId == aManagerId) {
@@ -253,7 +253,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot(
/* static */ already_AddRefed<DataSourceSurface> /* static */ already_AddRefed<DataSourceSurface>
CanvasManagerParent::GetCanvasSurface(dom::ContentParentId aContentId, CanvasManagerParent::GetCanvasSurface(dom::ContentParentId aContentId,
uint32_t aManagerId, int32_t aCanvasId, uint32_t aManagerId, ActorId aCanvasId,
uintptr_t aSurfaceId) { uintptr_t aSurfaceId) {
IProtocol* actor = GetCanvasActor(aContentId, aManagerId, aCanvasId); IProtocol* actor = GetCanvasActor(aContentId, aManagerId, aCanvasId);
if (!actor) { if (!actor) {

View File

@@ -47,16 +47,16 @@ class CanvasManagerParent final : public PCanvasManagerParent {
mozilla::ipc::IPCResult RecvInitialize(const uint32_t& aId); mozilla::ipc::IPCResult RecvInitialize(const uint32_t& aId);
mozilla::ipc::IPCResult RecvGetSnapshot( mozilla::ipc::IPCResult RecvGetSnapshot(
const uint32_t& aManagerId, const int32_t& aProtocolId, const uint32_t& aManagerId, const ActorId& aProtocolId,
const Maybe<RemoteTextureOwnerId>& aOwnerId, const Maybe<RemoteTextureOwnerId>& aOwnerId,
const Maybe<RawId>& aCommandEncoderId, const Maybe<RawId>& aCommandEncoderId,
webgl::FrontBufferSnapshotIpc* aResult); webgl::FrontBufferSnapshotIpc* aResult);
static mozilla::ipc::IProtocol* GetCanvasActor( static mozilla::ipc::IProtocol* GetCanvasActor(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId); dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId);
static already_AddRefed<DataSourceSurface> GetCanvasSurface( static already_AddRefed<DataSourceSurface> GetCanvasSurface(
dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId, dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId,
uintptr_t aSurfaceId); uintptr_t aSurfaceId);
private: private:

View File

@@ -10,6 +10,7 @@ include protocol PCanvas;
include protocol PWebGL; include protocol PWebGL;
include protocol PWebGPU; include protocol PWebGPU;
using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h";
using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h"; using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h";
using mozilla::webgl::FrontBufferSnapshotIpc from "mozilla/dom/WebGLIpdl.h"; using mozilla::webgl::FrontBufferSnapshotIpc from "mozilla/dom/WebGLIpdl.h";
using mozilla::webgpu::RawId from "mozilla/webgpu/WebGPUTypes.h"; using mozilla::webgpu::RawId from "mozilla/webgpu/WebGPUTypes.h";
@@ -46,7 +47,7 @@ parent:
// intended to be used by the main thread in the content process to block // intended to be used by the main thread in the content process to block
// reading without having to block on the worker thread that owns the context // reading without having to block on the worker thread that owns the context
// instance. // instance.
sync GetSnapshot(uint32_t aManagerId, int32_t aProtocolId, RemoteTextureOwnerId? ownerId, RawId? commandEncoderId) returns (FrontBufferSnapshotIpc ret); sync GetSnapshot(uint32_t aManagerId, ActorId aProtocolId, RemoteTextureOwnerId? ownerId, RawId? commandEncoderId) returns (FrontBufferSnapshotIpc ret);
}; };
} // gfx } // gfx

View File

@@ -765,7 +765,7 @@ already_AddRefed<gfx::SourceSurface> CanvasChild::SnapshotExternalCanvas(
RecordedResolveExternalSnapshot(syncId, gfx::ReferencePtr(surface))); RecordedResolveExternalSnapshot(syncId, gfx::ReferencePtr(surface)));
uint32_t managerId = static_cast<gfx::CanvasManagerChild*>(Manager())->Id(); uint32_t managerId = static_cast<gfx::CanvasManagerChild*>(Manager())->Id();
int32_t canvasId = aActor->Id(); ActorId canvasId = aActor->Id();
// Actually send the request via IPDL to snapshot the external WebGL canvas. // Actually send the request via IPDL to snapshot the external WebGL canvas.
SendSnapshotExternalCanvas(syncId, managerId, canvasId); SendSnapshotExternalCanvas(syncId, managerId, canvasId);

View File

@@ -1660,7 +1660,7 @@ void CanvasTranslator::SyncTranslation(uint64_t aSyncId) {
} }
mozilla::ipc::IPCResult CanvasTranslator::RecvSnapshotExternalCanvas( mozilla::ipc::IPCResult CanvasTranslator::RecvSnapshotExternalCanvas(
uint64_t aSyncId, uint32_t aManagerId, int32_t aCanvasId) { uint64_t aSyncId, uint32_t aManagerId, ActorId aCanvasId) {
if (NS_WARN_IF(!IsInTaskQueue())) { if (NS_WARN_IF(!IsInTaskQueue())) {
return IPC_FAIL(this, return IPC_FAIL(this,
"RecvSnapshotExternalCanvas used outside of task queue."); "RecvSnapshotExternalCanvas used outside of task queue.");

View File

@@ -196,7 +196,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
*/ */
mozilla::ipc::IPCResult RecvSnapshotExternalCanvas(uint64_t aSyncId, mozilla::ipc::IPCResult RecvSnapshotExternalCanvas(uint64_t aSyncId,
uint32_t aManagerId, uint32_t aManagerId,
int32_t aCanvasId); ActorId aCanvasId);
/** /**
* Resolves the given sync-id from the recording stream to a snapshot from * Resolves the given sync-id from the recording stream to a snapshot from

View File

@@ -33,6 +33,7 @@ using mozilla::layers::CompositeProcessFencesHolderId from "mozilla/layers/Layer
using mozilla::wr::ExternalImageSource from "mozilla/webrender/WebRenderTypes.h"; using mozilla::wr::ExternalImageSource from "mozilla/webrender/WebRenderTypes.h";
using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h"; using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
using mozilla::layers::SurfaceDescriptorRemoteDecoderId from "mozilla/layers/LayersTypes.h"; using mozilla::layers::SurfaceDescriptorRemoteDecoderId from "mozilla/layers/LayersTypes.h";
using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h";
[MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h"; [MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h";
namespace mozilla { namespace mozilla {
@@ -207,7 +208,7 @@ struct SurfaceDescriptorShared
[Comparable] struct SurfaceDescriptorCanvasSurface { [Comparable] struct SurfaceDescriptorCanvasSurface {
uint32_t managerId; uint32_t managerId;
int32_t canvasId; ActorId canvasId;
uintptr_t surfaceId; uintptr_t surfaceId;
}; };

View File

@@ -12,6 +12,7 @@ include "mozilla/layers/CanvasTranslator.h";
using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h"; using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h";
using mozilla::layers::TextureType from "mozilla/layers/LayersTypes.h"; using mozilla::layers::TextureType from "mozilla/layers/LayersTypes.h";
using mozilla::gfx::BackendType from "mozilla/gfx/Types.h"; using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h";
[MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h"; [MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h";
[MoveOnly] using mozilla::ipc::MutableSharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h"; [MoveOnly] using mozilla::ipc::MutableSharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h";
@@ -69,7 +70,7 @@ parent:
/** /**
* Snapshot an external canvas and label it for later lookup under a sync-id. * Snapshot an external canvas and label it for later lookup under a sync-id.
*/ */
async SnapshotExternalCanvas(uint64_t aSyncId, uint32_t aManagerId, int32_t aCanvasId); async SnapshotExternalCanvas(uint64_t aSyncId, uint32_t aManagerId, ActorId aCanvasId);
async __delete__(); async __delete__();

View File

@@ -127,6 +127,7 @@ Pickle::Pickle(uint32_t header_size, size_t segment_capacity)
DCHECK(static_cast<memberAlignmentType>(header_size) >= sizeof(Header)); DCHECK(static_cast<memberAlignmentType>(header_size) >= sizeof(Header));
DCHECK(header_size_ <= kHeaderSegmentCapacity); DCHECK(header_size_ <= kHeaderSegmentCapacity);
header_ = reinterpret_cast<Header*>(buffers_.Start()); header_ = reinterpret_cast<Header*>(buffers_.Start());
memset(header_, 0, header_size_);
header_->payload_size = 0; header_->payload_size = 0;
} }

View File

@@ -217,6 +217,8 @@ class Pickle {
struct Header { struct Header {
uint32_t payload_size; // Specifies the size of the payload. uint32_t payload_size; // Specifies the size of the payload.
}; };
static_assert(std::has_unique_object_representations_v<Header>,
"Header must not contain padding bytes");
// Returns the header, cast to a user-specified type T. The type T must be a // Returns the header, cast to a user-specified type T. The type T must be a
// subclass of Header and its size must correspond to the header_size passed // subclass of Header and its size must correspond to the header_size passed

View File

@@ -21,7 +21,7 @@ const mojo::core::ports::UserMessage::TypeInfo Message::kUserMessageTypeInfo{};
Message::~Message() { MOZ_COUNT_DTOR(IPC::Message); } Message::~Message() { MOZ_COUNT_DTOR(IPC::Message); }
Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity, Message::Message(routeid_t routing_id, msgid_t type, uint32_t segment_capacity,
HeaderFlags flags) HeaderFlags flags)
: UserMessage(&kUserMessageTypeInfo), : UserMessage(&kUserMessageTypeInfo),
Pickle(sizeof(Header), segment_capacity) { Pickle(sizeof(Header), segment_capacity) {
@@ -37,6 +37,7 @@ Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity,
header()->num_send_rights = 0; header()->num_send_rights = 0;
#endif #endif
header()->event_footer_size = 0; header()->event_footer_size = 0;
header()->_padding = 0;
} }
Message::Message(const char* data, int data_len) Message::Message(const char* data, int data_len)
@@ -46,7 +47,7 @@ Message::Message(const char* data, int data_len)
} }
/*static*/ mozilla::UniquePtr<Message> Message::IPDLMessage( /*static*/ mozilla::UniquePtr<Message> Message::IPDLMessage(
int32_t routing_id, msgid_t type, uint32_t segment_capacity, routeid_t routing_id, msgid_t type, uint32_t segment_capacity,
HeaderFlags flags) { HeaderFlags flags) {
return mozilla::MakeUnique<Message>(routing_id, type, segment_capacity, return mozilla::MakeUnique<Message>(routing_id, type, segment_capacity,
flags); flags);

View File

@@ -50,7 +50,9 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
public: public:
static const TypeInfo kUserMessageTypeInfo; static const TypeInfo kUserMessageTypeInfo;
typedef uint32_t msgid_t; using routeid_t = int64_t;
using msgid_t = uint32_t;
using seqno_t = int64_t;
enum NestedLevel { enum NestedLevel {
NOT_NESTED = 1, NOT_NESTED = 1,
@@ -175,8 +177,8 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
// Initialize a message with a user-defined type, priority value, and // Initialize a message with a user-defined type, priority value, and
// destination WebView ID. // destination WebView ID.
Message(int32_t routing_id, msgid_t type, Message(routeid_t routing_id, msgid_t type,
uint32_t segmentCapacity = 0, // 0 for the default capacity. uint32_t segment_capacity = 0, // 0 for the default capacity.
HeaderFlags flags = HeaderFlags()); HeaderFlags flags = HeaderFlags());
Message(const char* data, int data_len); Message(const char* data, int data_len);
@@ -190,7 +192,7 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
// the write latency of messages) of IPDL message creation. This helps // the write latency of messages) of IPDL message creation. This helps
// move the malloc and some of the parameter setting out of autogenerated // move the malloc and some of the parameter setting out of autogenerated
// code. // code.
static mozilla::UniquePtr<Message> IPDLMessage(int32_t routing_id, static mozilla::UniquePtr<Message> IPDLMessage(routeid_t routing_id,
msgid_t type, msgid_t type,
uint32_t segmentCapacity, uint32_t segmentCapacity,
HeaderFlags flags); HeaderFlags flags);
@@ -219,17 +221,17 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
msgid_t type() const { return header()->type; } msgid_t type() const { return header()->type; }
int32_t routing_id() const { return header()->routing; } routeid_t routing_id() const { return header()->routing; }
void set_routing_id(int32_t new_id) { header()->routing = new_id; } void set_routing_id(routeid_t new_id) { header()->routing = new_id; }
int32_t transaction_id() const { return header()->txid; } seqno_t transaction_id() const { return header()->txid; }
void set_transaction_id(int32_t txid) { header()->txid = txid; } void set_transaction_id(seqno_t txid) { header()->txid = txid; }
int32_t seqno() const { return header()->seqno; } seqno_t seqno() const { return header()->seqno; }
void set_seqno(int32_t aSeqno) { header()->seqno = aSeqno; } void set_seqno(seqno_t aSeqno) { header()->seqno = aSeqno; }
const char* name() const { return StringFromIPCMessageType(type()); } const char* name() const { return StringFromIPCMessageType(type()); }
@@ -369,22 +371,25 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
#endif #endif
struct Header : Pickle::Header { struct Header : Pickle::Header {
int32_t routing; // ID of the view that this message is destined for // Pickle::Header contains a 32-bit payload_size field
msgid_t type; // specifies the user-defined message type msgid_t type; // specifies the user-defined message type
HeaderFlags flags; // specifies control flags for the message HeaderFlags flags; // specifies control flags for the message
uint32_t event_footer_size; // Size of the message's event footer
routeid_t routing; // ID of the view that this message is destined for
seqno_t txid; // For sync messages, a transaction ID for message ordering.
seqno_t seqno; // Sequence number
uint32_t num_handles; // the number of handles included with this message uint32_t num_handles; // the number of handles included with this message
#if defined(XP_DARWIN) #if defined(XP_DARWIN)
uint32_t cookie; // cookie to ACK that the descriptors have been read. uint32_t cookie; // cookie to ACK that the descriptors have been read.
uint32_t num_send_rights; // the number of mach send rights included with uint32_t num_send_rights; // the number of mach send rights included with
// this message // this message
#endif #endif
// For sync messages, a transaction ID for message ordering. uint32_t _padding;
int32_t txid;
// Sequence number
int32_t seqno;
// Size of the message's event footer
uint32_t event_footer_size;
}; };
static_assert(std::has_unique_object_representations_v<Header>,
"Header must not contain padding bytes");
Header* header() { return headerT<Header>(); } Header* header() { return headerT<Header>(); }
const Header* header() const { return headerT<Header>(); } const Header* header() const { return headerT<Header>(); }
@@ -423,15 +428,12 @@ class Message : public mojo::core::ports::UserMessage, public Pickle {
} // namespace IPC } // namespace IPC
enum SpecialRoutingIDs { enum SpecialRoutingIDs : IPC::Message::routeid_t {
// indicates that we don't have a routing ID yet. // indicates that we don't have a routing ID yet.
MSG_ROUTING_NONE = kint32min, MSG_ROUTING_NONE = INT64_MIN,
// indicates a general message not sent to a particular tab. // indicates a general message not sent to a particular tab.
MSG_ROUTING_CONTROL = kint32max MSG_ROUTING_CONTROL = INT64_MAX
}; };
#define IPC_REPLY_ID 0xFFF0 // Special message id for replies
#define IPC_LOGGING_ID 0xFFF1 // Special message id for logging
#endif // CHROME_COMMON_IPC_MESSAGE_H__ #endif // CHROME_COMMON_IPC_MESSAGE_H__

View File

@@ -84,7 +84,7 @@ bool UntypedManagedEndpoint::BindCommon(IProtocol* aActor,
return false; return false;
} }
int32_t id = mInner->mId; ActorId id = mInner->mId;
mInner.reset(); mInner.reset();
// Our typed caller will insert the actor into the managed container. // Our typed caller will insert the actor into the managed container.

View File

@@ -231,9 +231,9 @@ class UntypedManagedEndpoint {
RefPtr<WeakActorLifecycleProxy> mOtherSide; RefPtr<WeakActorLifecycleProxy> mOtherSide;
RefPtr<WeakActorLifecycleProxy> mToplevel; RefPtr<WeakActorLifecycleProxy> mToplevel;
int32_t mId = 0; ActorId mId = 0;
ProtocolId mType = LastMsgIndex; ProtocolId mType = LastMsgIndex;
int32_t mManagerId = 0; ActorId mManagerId = 0;
ProtocolId mManagerType = LastMsgIndex; ProtocolId mManagerType = LastMsgIndex;
}; };
Maybe<Inner> mInner; Maybe<Inner> mInner;

View File

@@ -133,9 +133,10 @@ bool MessageChannel::sIsPumpingMessages = false;
class AutoEnterTransaction { class AutoEnterTransaction {
public: public:
explicit AutoEnterTransaction(MessageChannel* aChan, int32_t aMsgSeqno, explicit AutoEnterTransaction(MessageChannel* aChan,
int32_t aTransactionID, int aNestedLevel) IPC::Message::seqno_t aMsgSeqno,
MOZ_REQUIRES(*aChan->mMonitor) IPC::Message::seqno_t aTransactionID,
int aNestedLevel) MOZ_REQUIRES(*aChan->mMonitor)
: mChan(aChan), : mChan(aChan),
mActive(true), mActive(true),
mOutgoing(true), mOutgoing(true),
@@ -234,12 +235,12 @@ class AutoEnterTransaction {
return mNestedLevel; return mNestedLevel;
} }
int32_t SequenceNumber() const { IPC::Message::seqno_t SequenceNumber() const {
MOZ_RELEASE_ASSERT(mActive); MOZ_RELEASE_ASSERT(mActive);
return mSeqno; return mSeqno;
} }
int32_t TransactionID() const { IPC::Message::seqno_t TransactionID() const {
MOZ_RELEASE_ASSERT(mActive); MOZ_RELEASE_ASSERT(mActive);
return mTransaction; return mTransaction;
} }
@@ -248,7 +249,7 @@ class AutoEnterTransaction {
MOZ_RELEASE_ASSERT(aMessage->seqno() == mSeqno); MOZ_RELEASE_ASSERT(aMessage->seqno() == mSeqno);
MOZ_RELEASE_ASSERT(aMessage->transaction_id() == mTransaction); MOZ_RELEASE_ASSERT(aMessage->transaction_id() == mTransaction);
MOZ_RELEASE_ASSERT(!mReply); MOZ_RELEASE_ASSERT(!mReply);
IPC_LOG("Reply received on worker thread: seqno=%d", mSeqno); IPC_LOG("Reply received on worker thread: seqno=%" PRId64, mSeqno);
mReply = std::move(aMessage); mReply = std::move(aMessage);
MOZ_RELEASE_ASSERT(IsComplete()); MOZ_RELEASE_ASSERT(IsComplete());
} }
@@ -297,8 +298,8 @@ class AutoEnterTransaction {
// Properties of the message being sent/received. // Properties of the message being sent/received.
int mNestedLevel; int mNestedLevel;
int32_t mSeqno; IPC::Message::seqno_t mSeqno;
int32_t mTransaction; IPC::Message::seqno_t mTransaction;
// Next item in mChan->mTransactionStack. // Next item in mChan->mTransactionStack.
AutoEnterTransaction* mNext; AutoEnterTransaction* mNext;
@@ -497,7 +498,7 @@ void MessageChannel::AssertMaybeDeferredCountCorrect() {
// function is only called when the current transaction is known to be for a // function is only called when the current transaction is known to be for a
// NESTED_INSIDE_SYNC message. In that case, we know for sure what the caller is // NESTED_INSIDE_SYNC message. In that case, we know for sure what the caller is
// looking for. // looking for.
int32_t MessageChannel::CurrentNestedInsideSyncTransaction() const { auto MessageChannel::CurrentNestedInsideSyncTransaction() const -> seqno_t {
mMonitor->AssertCurrentThreadOwns(); mMonitor->AssertCurrentThreadOwns();
if (!mTransactionStack) { if (!mTransactionStack) {
return 0; return 0;
@@ -710,7 +711,7 @@ bool MessageChannel::OpenOnSameThread(MessageChannel* aTargetChan,
Open(std::move(porta), aSide, channelId, currentThread); Open(std::move(porta), aSide, channelId, currentThread);
} }
bool MessageChannel::Send(UniquePtr<Message> aMsg, int32_t* aSeqno) { bool MessageChannel::Send(UniquePtr<Message> aMsg, seqno_t* aSeqno) {
MOZ_RELEASE_ASSERT(!aMsg->is_sync()); MOZ_RELEASE_ASSERT(!aMsg->is_sync());
MOZ_RELEASE_ASSERT(aMsg->nested_level() != IPC::Message::NESTED_INSIDE_SYNC); MOZ_RELEASE_ASSERT(aMsg->nested_level() != IPC::Message::NESTED_INSIDE_SYNC);
MOZ_RELEASE_ASSERT(aMsg->routing_id() != MSG_ROUTING_NONE); MOZ_RELEASE_ASSERT(aMsg->routing_id() != MSG_ROUTING_NONE);
@@ -843,7 +844,7 @@ bool MessageChannel::SendBuildIDsMatchMessage(const char* aParentBuildID) {
class CancelMessage : public IPC::Message { class CancelMessage : public IPC::Message {
public: public:
explicit CancelMessage(int transaction) explicit CancelMessage(seqno_t transaction)
: IPC::Message(MSG_ROUTING_NONE, CANCEL_MESSAGE_TYPE) { : IPC::Message(MSG_ROUTING_NONE, CANCEL_MESSAGE_TYPE) {
set_transaction_id(transaction); set_transaction_id(transaction);
} }
@@ -1001,12 +1002,12 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr<Message> aMsg) {
// If we're awaiting a sync reply, we know that it needs to be immediately // If we're awaiting a sync reply, we know that it needs to be immediately
// handled to unblock us. // handled to unblock us.
if (aMsg->is_sync() && aMsg->is_reply()) { if (aMsg->is_sync() && aMsg->is_reply()) {
IPC_LOG("Received reply seqno=%d xid=%d", aMsg->seqno(), IPC_LOG("Received reply seqno=%" PRId64 " xid=%" PRId64, aMsg->seqno(),
aMsg->transaction_id()); aMsg->transaction_id());
if (aMsg->seqno() == mTimedOutMessageSeqno) { if (aMsg->seqno() == mTimedOutMessageSeqno) {
// Drop the message, but allow future sync messages to be sent. // Drop the message, but allow future sync messages to be sent.
IPC_LOG("Received reply to timedout message; igoring; xid=%d", IPC_LOG("Received reply to timedout message; igoring; xid=%" PRId64,
mTimedOutMessageSeqno); mTimedOutMessageSeqno);
EndTimeout(); EndTimeout();
return; return;
@@ -1062,8 +1063,9 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr<Message> aMsg) {
bool shouldWakeUp = AwaitingSyncReply() && !ShouldDeferMessage(*aMsg); bool shouldWakeUp = AwaitingSyncReply() && !ShouldDeferMessage(*aMsg);
IPC_LOG("Receive from link; seqno=%d, xid=%d, shouldWakeUp=%d", aMsg->seqno(), IPC_LOG("Receive from link; seqno=%" PRId64 ", xid=%" PRId64
aMsg->transaction_id(), shouldWakeUp); ", shouldWakeUp=%d",
aMsg->seqno(), aMsg->transaction_id(), shouldWakeUp);
struct FlowMarkerDispatch { struct FlowMarkerDispatch {
FlowMarkerDispatch(msgid_t type, Flow flow) : type(type), flow(flow) { FlowMarkerDispatch(msgid_t type, Flow flow) : type(type), flow(flow) {
@@ -1086,8 +1088,8 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr<Message> aMsg) {
// We want this marker to span the time when Post is called so that we // We want this marker to span the time when Post is called so that we
// can inherit the connection to the runnable. // can inherit the connection to the runnable.
FlowMarkerDispatch marker( FlowMarkerDispatch marker(
aMsg->type(), aMsg->type(), Flow::Global(static_cast<uint64_t>(aMsg->seqno()) ^
Flow::Global(aMsg->seqno() ^ LossyNarrowChannelId(mMessageChannelId))); LossyNarrowChannelId(mMessageChannelId)));
// There are two cases we're concerned about, relating to the state of the // There are two cases we're concerned about, relating to the state of the
// worker thread: // worker thread:
@@ -1149,7 +1151,7 @@ void MessageChannel::ProcessPendingRequests(
return; return;
} }
IPC_LOG("ProcessPendingRequests for seqno=%d, xid=%d", IPC_LOG("ProcessPendingRequests for seqno=%" PRId64 ", xid=%" PRId64,
aTransaction.SequenceNumber(), aTransaction.TransactionID()); aTransaction.SequenceNumber(), aTransaction.TransactionID());
// Loop until there aren't any more nested messages to process. // Loop until there aren't any more nested messages to process.
@@ -1176,7 +1178,8 @@ void MessageChannel::ProcessPendingRequests(
// Only log the interesting messages. // Only log the interesting messages.
if (msg->is_sync() || if (msg->is_sync() ||
msg->nested_level() == IPC::Message::NESTED_INSIDE_CPOW) { msg->nested_level() == IPC::Message::NESTED_INSIDE_CPOW) {
IPC_LOG("ShouldDeferMessage(seqno=%d) = %d", msg->seqno(), defer); IPC_LOG("ShouldDeferMessage(seqno=%" PRId64 ") = %d", msg->seqno(),
defer);
} }
if (!defer) { if (!defer) {
@@ -1292,7 +1295,7 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
aMsg->set_seqno(NextSeqno()); aMsg->set_seqno(NextSeqno());
int32_t seqno = aMsg->seqno(); seqno_t seqno = aMsg->seqno();
int nestedLevel = aMsg->nested_level(); int nestedLevel = aMsg->nested_level();
msgid_t replyType = aMsg->type() + 1; msgid_t replyType = aMsg->type() + 1;
@@ -1304,12 +1307,12 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
// message we're sending). // message we're sending).
bool nest = bool nest =
stackTop && stackTop->NestedLevel() == IPC::Message::NESTED_INSIDE_SYNC; stackTop && stackTop->NestedLevel() == IPC::Message::NESTED_INSIDE_SYNC;
int32_t transaction = nest ? stackTop->TransactionID() : seqno; seqno_t transaction = nest ? stackTop->TransactionID() : seqno;
aMsg->set_transaction_id(transaction); aMsg->set_transaction_id(transaction);
AutoEnterTransaction transact(this, seqno, transaction, nestedLevel); AutoEnterTransaction transact(this, seqno, transaction, nestedLevel);
IPC_LOG("Send seqno=%d, xid=%d", seqno, transaction); IPC_LOG("Send seqno=%" PRId64 ", xid=%" PRId64, seqno, transaction);
// aMsg will be destroyed soon, let's keep its type. // aMsg will be destroyed soon, let's keep its type.
const char* msgName = aMsg->name(); const char* msgName = aMsg->name();
@@ -1365,7 +1368,7 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
break; break;
} }
IPC_LOG("Timing out Send: xid=%d", transaction); IPC_LOG("Timing out Send: xid=%" PRId64, transaction);
mTimedOutMessageSeqno = seqno; mTimedOutMessageSeqno = seqno;
mTimedOutMessageNestedLevel = nestedLevel; mTimedOutMessageNestedLevel = nestedLevel;
@@ -1379,20 +1382,22 @@ bool MessageChannel::Send(UniquePtr<Message> aMsg, UniquePtr<Message>* aReply) {
} }
if (transact.IsCanceled()) { if (transact.IsCanceled()) {
IPC_LOG("Other side canceled seqno=%d, xid=%d", seqno, transaction); IPC_LOG("Other side canceled seqno=%" PRId64 ", xid=%" PRId64, seqno,
transaction);
mLastSendError = SyncSendError::CancelledAfterSend; mLastSendError = SyncSendError::CancelledAfterSend;
return false; return false;
} }
if (transact.IsError()) { if (transact.IsError()) {
IPC_LOG("Error: seqno=%d, xid=%d", seqno, transaction); IPC_LOG("Error: seqno=%" PRId64 ", xid=%" PRId64, seqno, transaction);
mLastSendError = SyncSendError::ReplyError; mLastSendError = SyncSendError::ReplyError;
return false; return false;
} }
uint32_t latencyMs = round((TimeStamp::Now() - start).ToMilliseconds()); uint32_t latencyMs = round((TimeStamp::Now() - start).ToMilliseconds());
IPC_LOG("Got reply: seqno=%d, xid=%d, msgName=%s, latency=%ums", seqno, IPC_LOG("Got reply: seqno=%" PRId64 ", xid=%" PRId64
transaction, msgName, latencyMs); ", msgName=%s, latency=%ums",
seqno, transaction, msgName, latencyMs);
UniquePtr<Message> reply = transact.GetReply(); UniquePtr<Message> reply = transact.GetReply();
@@ -1420,7 +1425,7 @@ bool MessageChannel::ProcessPendingRequest(ActorLifecycleProxy* aProxy,
AssertWorkerThread(); AssertWorkerThread();
mMonitor->AssertCurrentThreadOwns(); mMonitor->AssertCurrentThreadOwns();
IPC_LOG("Process pending: seqno=%d, xid=%d", aUrgent->seqno(), IPC_LOG("Process pending: seqno=%" PRId64 ", xid=%" PRId64, aUrgent->seqno(),
aUrgent->transaction_id()); aUrgent->transaction_id());
// keep the error relevant information // keep the error relevant information
@@ -1694,14 +1699,14 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy,
} }
#endif #endif
IPC_LOG("DispatchMessage: seqno=%d, xid=%d", aMsg->seqno(), IPC_LOG("DispatchMessage: seqno=%" PRId64 ", xid=%" PRId64, aMsg->seqno(),
aMsg->transaction_id()); aMsg->transaction_id());
AddProfilerMarker(*aMsg, MessageDirection::eReceiving); AddProfilerMarker(*aMsg, MessageDirection::eReceiving);
{ {
AutoEnterTransaction transaction(this, *aMsg); AutoEnterTransaction transaction(this, *aMsg);
int id = aMsg->transaction_id(); seqno_t id = aMsg->transaction_id();
MOZ_RELEASE_ASSERT(!aMsg->is_sync() || id == transaction.TransactionID()); MOZ_RELEASE_ASSERT(!aMsg->is_sync() || id == transaction.TransactionID());
{ {
@@ -1721,7 +1726,8 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy,
if (reply && transaction.IsCanceled()) { if (reply && transaction.IsCanceled()) {
// The transaction has been canceled. Don't send a reply. // The transaction has been canceled. Don't send a reply.
IPC_LOG("Nulling out reply due to cancellation, seqno=%d, xid=%d", IPC_LOG("Nulling out reply due to cancellation, seqno=%" PRId64
", xid=%" PRId64,
aMsg->seqno(), id); aMsg->seqno(), id);
reply = nullptr; reply = nullptr;
} }
@@ -1734,7 +1740,7 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy,
#endif #endif
if (reply && ChannelConnected == mChannelState) { if (reply && ChannelConnected == mChannelState) {
IPC_LOG("Sending reply seqno=%d, xid=%d", aMsg->seqno(), IPC_LOG("Sending reply seqno=%" PRId64 ", xid=%" PRId64, aMsg->seqno(),
aMsg->transaction_id()); aMsg->transaction_id());
AddProfilerMarker(*reply, MessageDirection::eSending); AddProfilerMarker(*reply, MessageDirection::eSending);
@@ -2263,7 +2269,7 @@ void MessageChannel::AddProfilerMarker(const IPC::Message& aMessage,
void MessageChannel::EndTimeout() { void MessageChannel::EndTimeout() {
mMonitor->AssertCurrentThreadOwns(); mMonitor->AssertCurrentThreadOwns();
IPC_LOG("Ending timeout of seqno=%d", mTimedOutMessageSeqno); IPC_LOG("Ending timeout of seqno=%" PRId64, mTimedOutMessageSeqno);
mTimedOutMessageSeqno = 0; mTimedOutMessageSeqno = 0;
mTimedOutMessageNestedLevel = 0; mTimedOutMessageNestedLevel = 0;
@@ -2303,7 +2309,7 @@ void MessageChannel::RepostAllMessages() {
AssertMaybeDeferredCountCorrect(); AssertMaybeDeferredCountCorrect();
} }
void MessageChannel::CancelTransaction(int transaction) { void MessageChannel::CancelTransaction(seqno_t transaction) {
mMonitor->AssertCurrentThreadOwns(); mMonitor->AssertCurrentThreadOwns();
// When we cancel a transaction, we need to behave as if there's no longer // When we cancel a transaction, we need to behave as if there's no longer
@@ -2316,13 +2322,13 @@ void MessageChannel::CancelTransaction(int transaction) {
// tampered with (by us). If so, they don't reset the variable to the old // tampered with (by us). If so, they don't reset the variable to the old
// value. // value.
IPC_LOG("CancelTransaction: xid=%d", transaction); IPC_LOG("CancelTransaction: xid=%" PRId64, transaction);
// An unusual case: We timed out a transaction which the other side then // An unusual case: We timed out a transaction which the other side then
// cancelled. In this case we just leave the timedout state and try to // cancelled. In this case we just leave the timedout state and try to
// forget this ever happened. // forget this ever happened.
if (transaction == mTimedOutMessageSeqno) { if (transaction == mTimedOutMessageSeqno) {
IPC_LOG("Cancelled timed out message %d", mTimedOutMessageSeqno); IPC_LOG("Cancelled timed out message %" PRId64, mTimedOutMessageSeqno);
EndTimeout(); EndTimeout();
// Normally mCurrentTransaction == 0 here. But it can be non-zero if: // Normally mCurrentTransaction == 0 here. But it can be non-zero if:
@@ -2353,8 +2359,8 @@ void MessageChannel::CancelTransaction(int transaction) {
if (msg->is_sync() && msg->nested_level() != IPC::Message::NOT_NESTED) { if (msg->is_sync() && msg->nested_level() != IPC::Message::NOT_NESTED) {
MOZ_RELEASE_ASSERT(!foundSync); MOZ_RELEASE_ASSERT(!foundSync);
MOZ_RELEASE_ASSERT(msg->transaction_id() != transaction); MOZ_RELEASE_ASSERT(msg->transaction_id() != transaction);
IPC_LOG("Removing msg from queue seqno=%d xid=%d", msg->seqno(), IPC_LOG("Removing msg from queue seqno=%" PRId64 " xid=%" PRId64,
msg->transaction_id()); msg->seqno(), msg->transaction_id());
foundSync = true; foundSync = true;
if (!IsAlwaysDeferred(*msg)) { if (!IsAlwaysDeferred(*msg)) {
mMaybeDeferredPendingCount--; mMaybeDeferredPendingCount--;
@@ -2379,7 +2385,7 @@ void MessageChannel::CancelCurrentTransaction() {
mListener->IntentionalCrash(); mListener->IntentionalCrash();
} }
IPC_LOG("Cancel requested: current xid=%d", IPC_LOG("Cancel requested: current xid=%" PRId64,
CurrentNestedInsideSyncTransaction()); CurrentNestedInsideSyncTransaction());
MOZ_RELEASE_ASSERT(DispatchingSyncMessage()); MOZ_RELEASE_ASSERT(DispatchingSyncMessage());
auto cancel = auto cancel =

View File

@@ -114,6 +114,7 @@ class MessageChannel : HasResultCodes {
public: public:
using Message = IPC::Message; using Message = IPC::Message;
using seqno_t = Message::seqno_t;
static constexpr int32_t kNoTimeout = INT32_MIN; static constexpr int32_t kNoTimeout = INT32_MIN;
@@ -205,7 +206,7 @@ class MessageChannel : HasResultCodes {
// Asynchronously send a message to the other side of the channel. // Asynchronously send a message to the other side of the channel.
// If aSeqno is non-null, it will be set to the seqno of the sent message. // If aSeqno is non-null, it will be set to the seqno of the sent message.
bool Send(UniquePtr<Message> aMsg, int32_t* aSeqno = nullptr) bool Send(UniquePtr<Message> aMsg, seqno_t* aSeqno = nullptr)
MOZ_EXCLUDES(*mMonitor); MOZ_EXCLUDES(*mMonitor);
bool SendBuildIDsMatchMessage(const char* aParentBuildID) bool SendBuildIDsMatchMessage(const char* aParentBuildID)
@@ -361,12 +362,13 @@ class MessageChannel : HasResultCodes {
bool ShouldContinueFromTimeout() MOZ_REQUIRES(*mMonitor); bool ShouldContinueFromTimeout() MOZ_REQUIRES(*mMonitor);
void EndTimeout() MOZ_REQUIRES(*mMonitor); void EndTimeout() MOZ_REQUIRES(*mMonitor);
void CancelTransaction(int transaction) MOZ_REQUIRES(*mMonitor); void CancelTransaction(seqno_t transaction) MOZ_REQUIRES(*mMonitor);
void RepostAllMessages() MOZ_REQUIRES(*mMonitor); void RepostAllMessages() MOZ_REQUIRES(*mMonitor);
int32_t NextSeqno() { seqno_t NextSeqno() {
AssertWorkerThread(); AssertWorkerThread();
MOZ_RELEASE_ASSERT(mozilla::Abs(mNextSeqno) < INT64_MAX, "seqno overflow");
return (mSide == ChildSide) ? --mNextSeqno : ++mNextSeqno; return (mSide == ChildSide) ? --mNextSeqno : ++mNextSeqno;
} }
@@ -420,7 +422,6 @@ class MessageChannel : HasResultCodes {
// Called to flush [LazySend] messages to the link. // Called to flush [LazySend] messages to the link.
void FlushLazySendMessages() MOZ_REQUIRES(*mMonitor); void FlushLazySendMessages() MOZ_REQUIRES(*mMonitor);
bool WasTransactionCanceled(int transaction);
bool ShouldDeferMessage(const Message& aMsg) MOZ_REQUIRES(*mMonitor); bool ShouldDeferMessage(const Message& aMsg) MOZ_REQUIRES(*mMonitor);
void OnMessageReceivedFromLink(UniquePtr<Message> aMsg) void OnMessageReceivedFromLink(UniquePtr<Message> aMsg)
MOZ_REQUIRES(*mMonitor); MOZ_REQUIRES(*mMonitor);
@@ -606,7 +607,7 @@ class MessageChannel : HasResultCodes {
// Worker-thread only; sequence numbers for messages that require // Worker-thread only; sequence numbers for messages that require
// replies. // replies.
int32_t mNextSeqno = 0; seqno_t mNextSeqno = 0;
static bool sIsPumpingMessages; static bool sIsPumpingMessages;
@@ -659,7 +660,7 @@ class MessageChannel : HasResultCodes {
friend class AutoEnterTransaction; friend class AutoEnterTransaction;
AutoEnterTransaction* mTransactionStack MOZ_GUARDED_BY(*mMonitor) = nullptr; AutoEnterTransaction* mTransactionStack MOZ_GUARDED_BY(*mMonitor) = nullptr;
int32_t CurrentNestedInsideSyncTransaction() const MOZ_REQUIRES(*mMonitor); seqno_t CurrentNestedInsideSyncTransaction() const MOZ_REQUIRES(*mMonitor);
bool AwaitingSyncReply() const MOZ_REQUIRES(*mMonitor); bool AwaitingSyncReply() const MOZ_REQUIRES(*mMonitor);
int AwaitingSyncReplyNestedLevel() const MOZ_REQUIRES(*mMonitor); int AwaitingSyncReplyNestedLevel() const MOZ_REQUIRES(*mMonitor);
@@ -686,7 +687,7 @@ class MessageChannel : HasResultCodes {
// A message is only timed out if it initiated a transaction. This avoids // A message is only timed out if it initiated a transaction. This avoids
// hitting a lot of corner cases with message nesting that we don't really // hitting a lot of corner cases with message nesting that we don't really
// care about. // care about.
int32_t mTimedOutMessageSeqno MOZ_GUARDED_BY(*mMonitor) = 0; seqno_t mTimedOutMessageSeqno MOZ_GUARDED_BY(*mMonitor) = 0;
int mTimedOutMessageNestedLevel MOZ_GUARDED_BY(*mMonitor) = 0; int mTimedOutMessageNestedLevel MOZ_GUARDED_BY(*mMonitor) = 0;
// Queue of all incoming messages. // Queue of all incoming messages.
@@ -754,7 +755,7 @@ struct IPCMarker {
static void StreamJSONMarkerData( static void StreamJSONMarkerData(
mozilla::baseprofiler::SpliceableJSONWriter& aWriter, mozilla::baseprofiler::SpliceableJSONWriter& aWriter,
mozilla::TimeStamp aStart, mozilla::TimeStamp aEnd, int32_t aOtherPid, mozilla::TimeStamp aStart, mozilla::TimeStamp aEnd, int32_t aOtherPid,
int32_t aMessageSeqno, IPC::Message::msgid_t aMessageType, IPC::Message::seqno_t aMessageSeqno, IPC::Message::msgid_t aMessageType,
mozilla::ipc::Side aSide, mozilla::ipc::MessageDirection aDirection, mozilla::ipc::Side aSide, mozilla::ipc::MessageDirection aDirection,
mozilla::ipc::MessagePhase aPhase, bool aSync, mozilla::ipc::MessagePhase aPhase, bool aSync,
mozilla::MarkerThreadId aOriginThreadId) { mozilla::MarkerThreadId aOriginThreadId) {

View File

@@ -46,21 +46,12 @@ struct ParamTraits<IPCMessageStart>
LastMsgIndex> {}; LastMsgIndex> {};
template <> template <>
struct ParamTraits<mozilla::ipc::ActorHandle> { struct ParamTraits<mozilla::ipc::IProtocol*> {
typedef mozilla::ipc::ActorHandle paramType; using paramType = mozilla::ipc::IProtocol*;
static void Write(MessageWriter* aWriter, const paramType& aParam) { static void Write(MessageWriter* aWriter, const paramType& aParam);
IPC::WriteParam(aWriter, aParam.mId);
}
static bool Read(MessageReader* aReader, paramType* aResult) { static bool Read(MessageReader* aReader, paramType* aResult);
int id;
if (IPC::ReadParam(aReader, &id)) {
aResult->mId = id;
return true;
}
return false;
}
}; };
template <> template <>

View File

@@ -337,12 +337,12 @@ IProtocol::~IProtocol() {
// The following methods either directly forward to the toplevel protocol, or // The following methods either directly forward to the toplevel protocol, or
// almost directly do. // almost directly do.
IProtocol* IProtocol::Lookup(int32_t aId) { return mToplevel->Lookup(aId); } IProtocol* IProtocol::Lookup(ActorId aId) { return mToplevel->Lookup(aId); }
Shmem IProtocol::CreateSharedMemory(size_t aSize, bool aUnsafe) { Shmem IProtocol::CreateSharedMemory(size_t aSize, bool aUnsafe) {
return mToplevel->CreateSharedMemory(aSize, aUnsafe); return mToplevel->CreateSharedMemory(aSize, aUnsafe);
} }
Shmem::Segment* IProtocol::LookupSharedMemory(int32_t aId) { Shmem::Segment* IProtocol::LookupSharedMemory(Shmem::id_t aId) {
return mToplevel->LookupSharedMemory(aId); return mToplevel->LookupSharedMemory(aId);
} }
bool IProtocol::IsTrackingSharedMemory(const Shmem::Segment* aSegment) { bool IProtocol::IsTrackingSharedMemory(const Shmem::Segment* aSegment) {
@@ -363,39 +363,6 @@ nsISerialEventTarget* IProtocol::GetActorEventTarget() {
return GetIPCChannel()->GetWorkerEventTarget(); return GetIPCChannel()->GetWorkerEventTarget();
} }
Maybe<IProtocol*> IProtocol::ReadActor(IPC::MessageReader* aReader,
bool aNullable,
const char* aActorDescription,
int32_t aProtocolTypeId) {
int32_t id;
if (!IPC::ReadParam(aReader, &id)) {
ActorIdReadError(aActorDescription);
return Nothing();
}
if (id == 1 || (id == 0 && !aNullable)) {
BadActorIdError(aActorDescription);
return Nothing();
}
if (id == 0) {
return Some(static_cast<IProtocol*>(nullptr));
}
IProtocol* listener = this->Lookup(id);
if (!listener) {
ActorLookupError(aActorDescription);
return Nothing();
}
if (listener->GetProtocolId() != aProtocolTypeId) {
MismatchedActorTypeError(aActorDescription);
return Nothing();
}
return Some(listener);
}
void IProtocol::FatalError(const char* const aErrorMsg) { void IProtocol::FatalError(const char* const aErrorMsg) {
HandleFatalError(aErrorMsg); HandleFatalError(aErrorMsg);
} }
@@ -457,7 +424,7 @@ void IProtocol::SetManager(IRefCountedProtocol* aManager) {
} }
bool IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager, bool IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager,
int32_t aId) { ActorId aId) {
MOZ_RELEASE_ASSERT(mLinkStatus == LinkStatus::Inactive, MOZ_RELEASE_ASSERT(mLinkStatus == LinkStatus::Inactive,
"Actor must be inactive to SetManagerAndRegister"); "Actor must be inactive to SetManagerAndRegister");
@@ -515,7 +482,8 @@ void IProtocol::UnlinkManager() {
mManager = nullptr; mManager = nullptr;
} }
bool IProtocol::ChannelSend(UniquePtr<IPC::Message> aMsg, int32_t* aSeqno) { bool IProtocol::ChannelSend(UniquePtr<IPC::Message> aMsg,
IPC::Message::seqno_t* aSeqno) {
if (CanSend()) { if (CanSend()) {
// NOTE: This send call failing can only occur during toplevel channel // NOTE: This send call failing can only occur during toplevel channel
// teardown. As this is an async call, this isn't reasonable to predict or // teardown. As this is an async call, this isn't reasonable to predict or
@@ -601,9 +569,8 @@ void IProtocol::ActorDisconnected(ActorDestroyReason aWhy) {
fuzzing::IPCFuzzController::instance().OnActorDestroyed(actor); fuzzing::IPCFuzzController::instance().OnActorDestroyed(actor);
#endif #endif
int32_t id = actor->mId; ActorId id = actor->mId;
if (IProtocol* manager = actor->Manager()) { if (IProtocol* manager = actor->Manager()) {
actor->mId = kFreedActorId;
auto entry = toplevel->mActorMap.Lookup(id); auto entry = toplevel->mActorMap.Lookup(id);
MOZ_DIAGNOSTIC_ASSERT(entry && *entry == actor->GetLifecycleProxy(), MOZ_DIAGNOSTIC_ASSERT(entry && *entry == actor->GetLifecycleProxy(),
"ID must be present and reference this actor"); "ID must be present and reference this actor");
@@ -673,7 +640,7 @@ IToplevelProtocol::IToplevelProtocol(const char* aName, ProtocolId aProtoId,
Side aSide) Side aSide)
: IRefCountedProtocol(aProtoId, aSide), : IRefCountedProtocol(aProtoId, aSide),
mOtherPid(base::kInvalidProcessId), mOtherPid(base::kInvalidProcessId),
mLastLocalId(0), mLastLocalId(kNullActorId),
mChannel(aName, this) { mChannel(aName, this) {
mToplevel = this; mToplevel = this;
} }
@@ -723,23 +690,15 @@ bool IToplevelProtocol::IsOnCxxStack() const {
return GetIPCChannel()->IsOnCxxStack(); return GetIPCChannel()->IsOnCxxStack();
} }
int32_t IToplevelProtocol::NextId() { int64_t IToplevelProtocol::NextId() {
// Generate the next ID to use for a shared memory or protocol. Parent and // Generate the next ID to use for a shared memory or protocol. Parent and
// Child sides of the protocol use different pools. // Child sides of the protocol use different pools.
int32_t tag = 0; MOZ_RELEASE_ASSERT(mozilla::Abs(mLastLocalId) < MSG_ROUTING_CONTROL - 1,
if (GetSide() == ParentSide) { "actor id overflow");
tag |= 1 << 1; return (GetSide() == ChildSide) ? --mLastLocalId : ++mLastLocalId;
}
// Check any overflow
MOZ_RELEASE_ASSERT(mLastLocalId < (1 << 29));
// Compute the ID to use with the low two bits as our tag, and the remaining
// bits as a monotonic.
return (++mLastLocalId << 2) | tag;
} }
IProtocol* IToplevelProtocol::Lookup(int32_t aId) { IProtocol* IToplevelProtocol::Lookup(ActorId aId) {
if (auto entry = mActorMap.Lookup(aId)) { if (auto entry = mActorMap.Lookup(aId)) {
return entry.Data()->Get(); return entry.Data()->Get();
} }
@@ -888,8 +847,8 @@ bool IPDLAsyncReturnsCallbacks::EntryKey::operator<(
(mSeqno == aOther.mSeqno && mType < aOther.mType); (mSeqno == aOther.mSeqno && mType < aOther.mType);
} }
void IPDLAsyncReturnsCallbacks::AddCallback(int32_t aSeqno, msgid_t aType, void IPDLAsyncReturnsCallbacks::AddCallback(IPC::Message::seqno_t aSeqno,
Callback aResolve, msgid_t aType, Callback aResolve,
RejectCallback aReject) { RejectCallback aReject) {
Entry entry{{aSeqno, aType}, std::move(aResolve), std::move(aReject)}; Entry entry{{aSeqno, aType}, std::move(aResolve), std::move(aReject)};
MOZ_ASSERT(!mMap.ContainsSorted(entry)); MOZ_ASSERT(!mMap.ContainsSorted(entry));
@@ -950,3 +909,46 @@ void IPDLAsyncReturnsCallbacks::RejectPendingResponses(
} // namespace ipc } // namespace ipc
} // namespace mozilla } // namespace mozilla
namespace IPC {
void ParamTraits<mozilla::ipc::IProtocol*>::Write(MessageWriter* aWriter,
const paramType& aParam) {
MOZ_RELEASE_ASSERT(aWriter->GetActor(),
"Cannot serialize managed actors without an actor");
mozilla::ipc::ActorId id = mozilla::ipc::IProtocol::kNullActorId;
if (aParam) {
id = aParam->Id();
MOZ_RELEASE_ASSERT(id != mozilla::ipc::IProtocol::kNullActorId,
"Actor has ID of 0?");
MOZ_RELEASE_ASSERT(aParam->CanSend(),
"Actor must still be open when sending");
MOZ_RELEASE_ASSERT(
aWriter->GetActor()->GetIPCChannel() == aParam->GetIPCChannel(),
"Actor must be from the same tree as the actor it is being sent over");
}
IPC::WriteParam(aWriter, id);
}
bool ParamTraits<mozilla::ipc::IProtocol*>::Read(MessageReader* aReader,
paramType* aResult) {
MOZ_RELEASE_ASSERT(aReader->GetActor(),
"Cannot serialize managed actors without an actor");
mozilla::ipc::ActorId id;
if (!IPC::ReadParam(aReader, &id)) {
return false;
}
if (id == mozilla::ipc::IProtocol::kNullActorId) {
*aResult = nullptr;
return true;
}
*aResult = aReader->GetActor()->Lookup(id);
return *aResult != nullptr;
}
} // namespace IPC

View File

@@ -124,9 +124,7 @@ struct EndpointProcInfo {
// Used to pass references to protocol actors across the wire. // Used to pass references to protocol actors across the wire.
// Actors created on the parent-side have a positive ID, and actors // Actors created on the parent-side have a positive ID, and actors
// allocated on the child side have a negative ID. // allocated on the child side have a negative ID.
struct ActorHandle { using ActorId = IPC::Message::routeid_t;
int mId;
};
enum class LinkStatus : uint8_t { enum class LinkStatus : uint8_t {
// The actor has not established a link yet, or the actor is no longer in use // The actor has not established a link yet, or the actor is no longer in use
@@ -194,10 +192,10 @@ class IProtocol : public HasResultCodes {
const IToplevelProtocol* ToplevelProtocol() const { return mToplevel; } const IToplevelProtocol* ToplevelProtocol() const { return mToplevel; }
// Lookup() is forwarded directly to the toplevel protocol. // Lookup() is forwarded directly to the toplevel protocol.
IProtocol* Lookup(int32_t aId); IProtocol* Lookup(ActorId aId);
Shmem CreateSharedMemory(size_t aSize, bool aUnsafe); Shmem CreateSharedMemory(size_t aSize, bool aUnsafe);
Shmem::Segment* LookupSharedMemory(int32_t aId); Shmem::Segment* LookupSharedMemory(ActorId aId);
bool IsTrackingSharedMemory(const Shmem::Segment* aSegment); bool IsTrackingSharedMemory(const Shmem::Segment* aSegment);
bool DestroySharedMemory(Shmem& aShmem); bool DestroySharedMemory(Shmem& aShmem);
@@ -213,7 +211,7 @@ class IProtocol : public HasResultCodes {
ProtocolId GetProtocolId() const { return mProtocolId; } ProtocolId GetProtocolId() const { return mProtocolId; }
const char* GetProtocolName() const { return ProtocolIdToName(mProtocolId); } const char* GetProtocolName() const { return ProtocolIdToName(mProtocolId); }
int32_t Id() const { return mId; } ActorId Id() const { return mId; }
IRefCountedProtocol* Manager() const { return mManager; } IRefCountedProtocol* Manager() const { return mManager; }
uint32_t AllManagedActorsCount() const; uint32_t AllManagedActorsCount() const;
@@ -232,11 +230,7 @@ class IProtocol : public HasResultCodes {
} }
// Deallocate a managee given its type. // Deallocate a managee given its type.
virtual void DeallocManagee(int32_t, IProtocol*) = 0; virtual void DeallocManagee(ProtocolId, IProtocol*) = 0;
Maybe<IProtocol*> ReadActor(IPC::MessageReader* aReader, bool aNullable,
const char* aActorDescription,
int32_t aProtocolTypeId);
virtual Result OnMessageReceived(const Message& aMessage) = 0; virtual Result OnMessageReceived(const Message& aMessage) = 0;
virtual Result OnMessageReceived(const Message& aMessage, virtual Result OnMessageReceived(const Message& aMessage,
@@ -255,6 +249,7 @@ class IProtocol : public HasResultCodes {
friend class ActorLifecycleProxy; friend class ActorLifecycleProxy;
friend class IPDLResolverInner; friend class IPDLResolverInner;
friend class UntypedManagedEndpoint; friend class UntypedManagedEndpoint;
friend struct IPC::ParamTraits<IProtocol*>;
// We have separate functions because the accessibility code and BrowserParent // We have separate functions because the accessibility code and BrowserParent
// manually calls SetManager. // manually calls SetManager.
@@ -269,10 +264,11 @@ class IProtocol : public HasResultCodes {
// its manager, setting up channels for the protocol as well. Not // its manager, setting up channels for the protocol as well. Not
// for use outside of IPDL. // for use outside of IPDL.
bool SetManagerAndRegister(IRefCountedProtocol* aManager, bool SetManagerAndRegister(IRefCountedProtocol* aManager,
int32_t aId = kNullActorId); ActorId aId = kNullActorId);
// Helpers for calling `Send` on our underlying IPC channel. // Helpers for calling `Send` on our underlying IPC channel.
bool ChannelSend(UniquePtr<IPC::Message> aMsg, int32_t* aSeqno = nullptr); bool ChannelSend(UniquePtr<IPC::Message> aMsg,
IPC::Message::seqno_t* aSeqno = nullptr);
bool ChannelSend(UniquePtr<IPC::Message> aMsg, bool ChannelSend(UniquePtr<IPC::Message> aMsg,
UniquePtr<IPC::Message>* aReply); UniquePtr<IPC::Message>* aReply);
@@ -311,8 +307,7 @@ class IProtocol : public HasResultCodes {
// The actor has been freed after this method returns. // The actor has been freed after this method returns.
virtual void ActorDealloc() = 0; virtual void ActorDealloc() = 0;
static const int32_t kNullActorId = 0; static const ActorId kNullActorId = 0;
static const int32_t kFreedActorId = 1;
private: private:
#ifdef DEBUG #ifdef DEBUG
@@ -327,7 +322,7 @@ class IProtocol : public HasResultCodes {
// identify managed actors to destroy when tearing down an actor tree. // identify managed actors to destroy when tearing down an actor tree.
IProtocol* PeekManagedActor() const; IProtocol* PeekManagedActor() const;
int32_t mId; ActorId mId;
const ProtocolId mProtocolId; const ProtocolId mProtocolId;
const Side mSide; const Side mSide;
LinkStatus mLinkStatus; LinkStatus mLinkStatus;
@@ -444,10 +439,10 @@ class IToplevelProtocol : public IRefCountedProtocol {
public: public:
// Shadows the method on IProtocol, which will forward to the top. // Shadows the method on IProtocol, which will forward to the top.
IProtocol* Lookup(int32_t aId); IProtocol* Lookup(Shmem::id_t aId);
Shmem CreateSharedMemory(size_t aSize, bool aUnsafe); Shmem CreateSharedMemory(size_t aSize, bool aUnsafe);
Shmem::Segment* LookupSharedMemory(int32_t aId); Shmem::Segment* LookupSharedMemory(Shmem::id_t aId);
bool IsTrackingSharedMemory(const Shmem::Segment* aSegment); bool IsTrackingSharedMemory(const Shmem::Segment* aSegment);
bool DestroySharedMemory(Shmem& aShmem); bool DestroySharedMemory(Shmem& aShmem);
@@ -546,17 +541,17 @@ class IToplevelProtocol : public IRefCountedProtocol {
GeckoChildID OtherChildIDMaybeInvalid() const { return mOtherChildID; } GeckoChildID OtherChildIDMaybeInvalid() const { return mOtherChildID; }
private: private:
int32_t NextId(); int64_t NextId();
template <class T> template <class T>
using IDMap = nsTHashMap<nsUint32HashKey, T>; using IDMap = nsTHashMap<int64_t, T>;
base::ProcessId mOtherPid; base::ProcessId mOtherPid;
GeckoChildID mOtherChildID; GeckoChildID mOtherChildID;
// NOTE NOTE NOTE // NOTE NOTE NOTE
// Used to be on mState // Used to be on mState
int32_t mLastLocalId; int64_t mLastLocalId;
IDMap<RefPtr<ActorLifecycleProxy>> mActorMap; IDMap<RefPtr<ActorLifecycleProxy>> mActorMap;
IDMap<RefPtr<Shmem::Segment>> mShmemMap; IDMap<RefPtr<Shmem::Segment>> mShmemMap;
@@ -761,16 +756,17 @@ class IPDLAsyncReturnsCallbacks : public HasResultCodes {
// the IPC::MessageReader* argument. // the IPC::MessageReader* argument.
using Callback = using Callback =
mozilla::MoveOnlyFunction<Result(IPC::MessageReader* IProtocol)>; mozilla::MoveOnlyFunction<Result(IPC::MessageReader* IProtocol)>;
using seqno_t = IPC::Message::seqno_t;
using msgid_t = IPC::Message::msgid_t; using msgid_t = IPC::Message::msgid_t;
void AddCallback(int32_t aSeqno, msgid_t aType, Callback aResolve, void AddCallback(seqno_t aSeqno, msgid_t aType, Callback aResolve,
RejectCallback aReject); RejectCallback aReject);
Result GotReply(IProtocol* aActor, const IPC::Message& aMessage); Result GotReply(IProtocol* aActor, const IPC::Message& aMessage);
void RejectPendingResponses(ResponseRejectReason aReason); void RejectPendingResponses(ResponseRejectReason aReason);
private: private:
struct EntryKey { struct EntryKey {
int32_t mSeqno; seqno_t mSeqno;
msgid_t mType; msgid_t mType;
bool operator==(const EntryKey& aOther) const; bool operator==(const EntryKey& aOther) const;

View File

@@ -20,7 +20,7 @@ class ShmemCreated : public IPC::Message {
typedef Shmem::id_t id_t; typedef Shmem::id_t id_t;
public: public:
ShmemCreated(int32_t routingId, id_t aIPDLId, ShmemCreated(routeid_t routingId, id_t aIPDLId,
MutableSharedMemoryHandle&& aHandle) MutableSharedMemoryHandle&& aHandle)
: IPC::Message( : IPC::Message(
routingId, SHMEM_CREATED_MESSAGE_TYPE, 0, routingId, SHMEM_CREATED_MESSAGE_TYPE, 0,
@@ -46,7 +46,7 @@ class ShmemDestroyed : public IPC::Message {
typedef Shmem::id_t id_t; typedef Shmem::id_t id_t;
public: public:
ShmemDestroyed(int32_t routingId, id_t aIPDLId) ShmemDestroyed(routeid_t routingId, id_t aIPDLId)
: IPC::Message( : IPC::Message(
routingId, SHMEM_DESTROYED_MESSAGE_TYPE, 0, routingId, SHMEM_DESTROYED_MESSAGE_TYPE, 0,
HeaderFlags(NOT_NESTED, NORMAL_PRIORITY, COMPRESSION_NONE, HeaderFlags(NOT_NESTED, NORMAL_PRIORITY, COMPRESSION_NONE,
@@ -127,7 +127,7 @@ Shmem::Builder::Builder(size_t aSize) : mSize(aSize) {
} }
std::tuple<UniquePtr<IPC::Message>, Shmem> Shmem::Builder::Build( std::tuple<UniquePtr<IPC::Message>, Shmem> Shmem::Builder::Build(
id_t aId, bool aUnsafe, int32_t aRoutingId) { id_t aId, bool aUnsafe, IPC::Message::routeid_t aRoutingId) {
Shmem shmem(std::move(mSegment), aId, mSize, aUnsafe); Shmem shmem(std::move(mSegment), aId, mSize, aUnsafe);
shmem.AssertInvariants(); shmem.AssertInvariants();
MOZ_ASSERT(mHandle, "null shmem handle"); MOZ_ASSERT(mHandle, "null shmem handle");
@@ -160,7 +160,8 @@ already_AddRefed<Shmem::Segment> Shmem::OpenExisting(
return MakeAndAddRef<Shmem::Segment>(std::move(mapping)); return MakeAndAddRef<Shmem::Segment>(std::move(mapping));
} }
UniquePtr<IPC::Message> Shmem::MkDestroyedMessage(int32_t routingId) { UniquePtr<IPC::Message> Shmem::MkDestroyedMessage(
IPC::Message::routeid_t routingId) {
AssertInvariants(); AssertInvariants();
return MakeUnique<ShmemDestroyed>(routingId, mId); return MakeUnique<ShmemDestroyed>(routingId, mId);
} }

View File

@@ -68,7 +68,7 @@ class Shmem final {
friend class IToplevelProtocol; friend class IToplevelProtocol;
public: public:
using id_t = int32_t; using id_t = int64_t;
// Low-level wrapper around platform shmem primitives. // Low-level wrapper around platform shmem primitives.
class Segment final : public SharedMemoryMapping { class Segment final : public SharedMemoryMapping {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Segment); NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Segment);
@@ -89,8 +89,8 @@ class Shmem final {
// Prepare this to be shared with another process. Return an IPC message // Prepare this to be shared with another process. Return an IPC message
// that contains enough information for the other process to map this // that contains enough information for the other process to map this
// segment in OpenExisting(), and the shmem. // segment in OpenExisting(), and the shmem.
std::tuple<UniquePtr<IPC::Message>, Shmem> Build(id_t aId, bool aUnsafe, std::tuple<UniquePtr<IPC::Message>, Shmem> Build(
int32_t aRoutingId); id_t aId, bool aUnsafe, IPC::Message::routeid_t aRoutingId);
private: private:
size_t mSize; size_t mSize;
@@ -169,7 +169,7 @@ class Shmem final {
// contains enough information for the other process to unmap this // contains enough information for the other process to unmap this
// segment. Return a new message if successful (owned by the // segment. Return a new message if successful (owned by the
// caller), nullptr if not. // caller), nullptr if not.
UniquePtr<IPC::Message> MkDestroyedMessage(int32_t routingId); UniquePtr<IPC::Message> MkDestroyedMessage(IPC::Message::routeid_t routingId);
// Return a Segment instance in this process using the descriptor shared // Return a Segment instance in this process using the descriptor shared
// to us by the process that created the underlying OS shmem resource. The // to us by the process that created the underlying OS shmem resource. The

View File

@@ -130,7 +130,7 @@ def _protocolId(ptype):
def _protocolIdType(): def _protocolIdType():
return Type.INT32 return Type("mozilla::ipc::ProtocolId")
def _actorName(pname, side): def _actorName(pname, side):
@@ -142,11 +142,7 @@ def _actorName(pname, side):
def _actorIdType(): def _actorIdType():
return Type.INT32 return Type("mozilla::ipc::ActorId")
def _actorTypeTagType():
return Type.INT32
def _actorId(actor=None): def _actorId(actor=None):
@@ -155,10 +151,6 @@ def _actorId(actor=None):
return ExprCall(ExprVar("Id")) return ExprCall(ExprVar("Id"))
def _actorHId(actorhandle):
return ExprSelect(actorhandle, ".", "mId")
def _deleteId(): def _deleteId():
return ExprVar("Msg___delete____ID") return ExprVar("Msg___delete____ID")
@@ -1822,7 +1814,7 @@ def _generateMessageConstructor(md, segmentSize, protocol, forReply=False):
func = FunctionDefn( func = FunctionDefn(
FunctionDecl( FunctionDecl(
clsname, clsname,
params=[Decl(Type("int32_t"), routingId.name)], params=[Decl(Type("IPC::Message::routeid_t"), routingId.name)],
ret=Type("mozilla::UniquePtr<IPC::Message>"), ret=Type("mozilla::UniquePtr<IPC::Message>"),
) )
) )
@@ -2144,53 +2136,38 @@ class _ParamTraits:
Write and read callers will perform nullability validation.""" Write and read callers will perform nullability validation."""
cxxtype = _cxxBareType(actortype, side, fq=True) cxxtype = _cxxBareType(actortype, side, fq=True)
basetype = Type("mozilla::ipc::IProtocol", ptr=True)
write = StmtCode( # void Write(..) impl - Write actor as IProtocol*
""" write = cls.checkedWrite(
MOZ_RELEASE_ASSERT( None,
${writervar}->GetActor(), ExprCast(cls.var, basetype, static=True),
"Cannot serialize managed actors without an actor"); cls.writervar,
sentinelKey=actortype.name(),
int32_t id;
if (!${var}) {
id = 0; // kNullActorId
} else {
id = ${var}->Id();
if (id == 1) { // kFreedActorId
${var}->FatalError("Actor has been |delete|d");
}
MOZ_RELEASE_ASSERT(
${writervar}->GetActor()->GetIPCChannel() == ${var}->GetIPCChannel(),
"Actor must be from the same channel as the"
" actor it's being sent over");
MOZ_RELEASE_ASSERT(
${var}->CanSend(),
"Actor must still be open when sending");
}
${write};
""",
var=cls.var,
writervar=cls.writervar,
write=cls.write(ExprVar("id"), cls.writervar),
) )
# bool Read(..) impl # bool Read(..) impl - Read actor as IProtocol*
read = StmtCode( read = StmtCode(
""" """
MOZ_RELEASE_ASSERT( ${read}
${readervar}->GetActor(), if (actor && actor->GetProtocolId() != ${protocolid}) {
"Cannot deserialize managed actors without an actor"); ${typeerror}
mozilla::Maybe<mozilla::ipc::IProtocol*> actor = ${readervar}->GetActor() return {};
->ReadActor(${readervar}, true, ${actortype}, ${protocolid});
if (actor.isSome()) {
return static_cast<${cxxtype}>(actor.ref());
} }
return {}; return static_cast<${cxxtype}>(actor);
""", """,
readervar=cls.readervar, read=cls._checkedRead(
actortype=ExprLiteral.String(actortype.name()), None,
basetype,
ExprVar("actor"),
sentinelKey=actortype.name(),
what="managed " + actortype.name() + " actor",
),
protocolid=_protocolId(actortype), protocolid=_protocolId(actortype),
typeerror=cls.fatalError(
cls.readervar,
"Unexpected actor type (expected " + actortype.name() + ")",
),
cxxtype=cxxtype, cxxtype=cxxtype,
) )
@@ -3350,7 +3327,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
self.nonForwardDeclaredHeaders = set() self.nonForwardDeclaredHeaders = set()
self.typedefSet = set( self.typedefSet = set(
[ [
Typedef(Type("mozilla::ipc::ActorHandle"), "ActorHandle"), Typedef(Type("mozilla::ipc::ActorId"), "ActorId"),
Typedef(Type("base::ProcessId"), "ProcessId"), Typedef(Type("base::ProcessId"), "ProcessId"),
Typedef(Type("mozilla::ipc::ProtocolId"), "ProtocolId"), Typedef(Type("mozilla::ipc::ProtocolId"), "ProtocolId"),
Typedef(Type("mozilla::ipc::Endpoint"), "Endpoint", ["FooSide"]), Typedef(Type("mozilla::ipc::Endpoint"), "Endpoint", ["FooSide"]),
@@ -4034,8 +4011,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
# for ctor recv cases, we can't read the actor ID into a PFoo* # for ctor recv cases, we can't read the actor ID into a PFoo*
# because it doesn't exist on this side yet. Use a "special" # because it doesn't exist on this side yet. Use a "special"
# actor handle instead # actor handle instead
handlevar = ExprVar("handle__") actoridvar = ExprVar("actorid__")
self.handlevar = handlevar self.actoridvar = actoridvar
msgtype = ExprCode("msg__.type()") msgtype = ExprCode("msg__.type()")
self.asyncSwitch = StmtSwitch(msgtype) self.asyncSwitch = StmtSwitch(msgtype)
@@ -4130,7 +4107,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
method.addcode( method.addcode(
""" """
int32_t route__ = ${msgvar}.routing_id(); IPC::Message::routeid_t route__ = ${msgvar}.routing_id();
if (MSG_ROUTING_CONTROL != route__) { if (MSG_ROUTING_CONTROL != route__) {
IProtocol* routed__ = Lookup(route__); IProtocol* routed__ = Lookup(route__);
if (!routed__ || !routed__->GetLifecycleProxy()) { if (!routed__ || !routed__->GetLifecycleProxy()) {
@@ -4762,7 +4739,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
def genCtorRecvCase(self, md): def genCtorRecvCase(self, md):
lbl = CaseLabel(md.pqMsgId()) lbl = CaseLabel(md.pqMsgId())
case = StmtBlock() case = StmtBlock()
actorhandle = self.handlevar
stmts = self.deserializeMessage( stmts = self.deserializeMessage(
md, self.side, errfnRecv, errfnSent=errfnSentinel(_Result.ValuError) md, self.side, errfnRecv, errfnSent=errfnSentinel(_Result.ValuError)
@@ -4778,7 +4754,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
# alloc the actor, register it under the foreign ID # alloc the actor, register it under the foreign ID
+ [self.callAllocActor(md, retsems="in", side=self.side)] + [self.callAllocActor(md, retsems="in", side=self.side)]
+ self.bindManagedActor( + self.bindManagedActor(
md.actorDecl(), errfn=_Result.ValuError, idexpr=_actorHId(actorhandle) md.actorDecl(), errfn=_Result.ValuError, idexpr=self.actoridvar
) )
+ [Whitespace.NL] + [Whitespace.NL]
+ saveIdStmts + saveIdStmts
@@ -4847,33 +4823,45 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
def makeMessage(self, md, errfn, fromActor=None): def makeMessage(self, md, errfn, fromActor=None):
msgvar = self.msgvar msgvar = self.msgvar
writervar = ExprVar("writer__") writervar = ExprVar("writer__")
isctor = md.decl.type.isCtor()
routingId = self.protocol.routingId(fromActor) routingId = self.protocol.routingId(fromActor)
this = fromActor or ExprVar.THIS this = fromActor or ExprVar.THIS
stmts = ( stmts = [
[ StmtDecl(
StmtDecl( Decl(Type("UniquePtr<IPC::Message>"), msgvar.name),
Decl(Type("UniquePtr<IPC::Message>"), msgvar.name), init=ExprCall(ExprVar(md.pqMsgCtorFunc()), args=[routingId]),
init=ExprCall(ExprVar(md.pqMsgCtorFunc()), args=[routingId]), ),
), StmtDecl(
StmtDecl( Decl(Type("IPC::MessageWriter"), writervar.name),
Decl(Type("IPC::MessageWriter"), writervar.name), initargs=[ExprDeref(msgvar), this],
initargs=[ExprDeref(msgvar), this], ),
), Whitespace.NL,
] ]
+ [Whitespace.NL]
+ [ start = 0
if isctor:
# serialize the actor as the raw actor ID so that it can be used to
# construct the "real" actor on the other side.
stmts += [
_ParamTraits.checkedWrite( _ParamTraits.checkedWrite(
p.ipdltype, None,
p.var(), _actorId(ExprVar("actor")),
ExprAddrOf(writervar), ExprAddrOf(writervar),
sentinelKey=p.name, sentinelKey="actorid",
) )
for p in md.params
] ]
+ [Whitespace.NL] start = 1
+ self.setMessageFlags(md, msgvar)
) stmts += [
_ParamTraits.checkedWrite(
p.ipdltype,
p.var(),
ExprAddrOf(writervar),
sentinelKey=p.name,
)
for p in md.params[start:]
]
return msgvar, stmts return msgvar, stmts
def makeResolver(self, md, errfn, routingId): def makeResolver(self, md, errfn, routingId):
@@ -4964,20 +4952,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
) )
for r in md.returns for r in md.returns
] ]
+ self.setMessageFlags(md, replyvar)
+ [self.logMessage(md, replyvar, "Sending reply ")] + [self.logMessage(md, replyvar, "Sending reply ")]
) )
def setMessageFlags(self, md, var, seqno=None):
stmts = []
if seqno:
stmts.append(
StmtExpr(ExprCall(ExprSelect(var, "->", "set_seqno"), args=[seqno]))
)
return stmts + [Whitespace.NL]
def deserializeMessage(self, md, side, errfn, errfnSent): def deserializeMessage(self, md, side, errfn, errfnSent):
msgvar = self.msgvar msgvar = self.msgvar
msgexpr = ExprAddrOf(msgvar) msgexpr = ExprAddrOf(msgvar)
@@ -4996,17 +4973,17 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
if isctor: if isctor:
# return the raw actor handle so that its ID can be used # return the raw actor handle so that its ID can be used
# to construct the "real" actor # to construct the "real" actor
handlevar = self.handlevar actoridvar = self.actoridvar
handletype = Type("ActorHandle") actoridtype = _actorIdType()
reads = [ reads = [
_ParamTraits.checkedRead( _ParamTraits.checkedRead(
None, None,
handletype, actoridtype,
handlevar, actoridvar,
ExprAddrOf(readervar), ExprAddrOf(readervar),
errfn, errfn,
"'%s'" % handletype.name, "'%s'" % actoridtype.name,
sentinelKey="actor", sentinelKey="actorid",
errfnSentinel=errfnSent, errfnSentinel=errfnSent,
) )
] ]
@@ -5066,27 +5043,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
StmtReturn(errcode), StmtReturn(errcode),
] ]
start, reads = 0, [] reads = [
if md.decl.type.isCtor():
# return the raw actor handle so that its ID can be used
# to construct the "real" actor
handlevar = self.handlevar
handletype = Type("ActorHandle")
reads = [
_ParamTraits.checkedRead(
None,
handletype,
handlevar,
readervar,
errfn,
"'%s'" % handletype.name,
sentinelKey="actor",
errfnSentinel=errfnSentinel(_Result.ValuError),
)
]
start = 1
reads += [
_ParamTraits.checkedRead( _ParamTraits.checkedRead(
p.ipdltype, p.ipdltype,
p.bareType(side), p.bareType(side),
@@ -5097,7 +5054,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
sentinelKey=p.name, sentinelKey=p.name,
errfnSentinel=errfnSentinel(_Result.ValuError), errfnSentinel=errfnSentinel(_Result.ValuError),
) )
for p in md.returns[start:] for p in md.returns
] ]
if len(md.returns) > 1: if len(md.returns) > 1:
@@ -5185,7 +5142,12 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
if actor is not None: if actor is not None:
send = ExprSelect(actor, "->", send.name) send = ExprSelect(actor, "->", send.name)
if md.returns: if md.returns:
stmts.append(StmtDecl(Decl(Type.INT32, seqno.name), init=ExprLiteral.ZERO)) stmts.append(
StmtDecl(
Decl(Type("IPC::Message::seqno_t"), seqno.name),
init=ExprLiteral.ZERO,
)
)
ifsendok = StmtIf( ifsendok = StmtIf(
ExprCall(send, args=[ExprMove(msgexpr), ExprAddrOf(seqno)]) ExprCall(send, args=[ExprMove(msgexpr), ExprAddrOf(seqno)])
) )

View File

@@ -326,52 +326,53 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
Maybe<PortName> portName = channel->GetPortName(); Maybe<PortName> portName = channel->GetPortName();
if (!portName) { if (!portName) {
MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %d Protocol: %s\n", MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
" Protocol: %s\n",
protocol->Id(), protocol->GetProtocolName()); protocol->Id(), protocol->GetProtocolName());
} }
if (portName) { if (portName) {
if (!protoIdFilter.empty()) { if (!protoIdFilter.empty()) {
if (!strcmp(protocol->GetProtocolName(), protoIdFilter.c_str())) { if (!strcmp(protocol->GetProtocolName(), protoIdFilter.c_str())) {
MOZ_FUZZING_NYX_PRINTF( MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
"INFO: [OnActorConnected] ActorID %d Protocol: %s matches " " Protocol: %s matches "
"target.\n", "target.\n",
protocol->Id(), protocol->GetProtocolName()); protocol->Id(), protocol->GetProtocolName());
// If our matching protocol is not a toplevel actor, then we need to // If our matching protocol is not a toplevel actor, then we need to
// exclude the toplevel protocol later in `MakeTargetDecision` because // exclude the toplevel protocol later in `MakeTargetDecision` because
// the actor will always be added to the map. // the actor will always be added to the map.
protoFilterTargetExcludeToplevel = protocol->Manager() != nullptr; protoFilterTargetExcludeToplevel = protocol->Manager() != nullptr;
} else if (actorIds[*portName].empty()) { } else if (actorIds[*portName].empty()) {
MOZ_FUZZING_NYX_PRINTF( MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
"INFO: [OnActorConnected] ActorID %d Protocol: %s is toplevel " " Protocol: %s is toplevel "
"actor.\n", "actor.\n",
protocol->Id(), protocol->GetProtocolName()); protocol->Id(), protocol->GetProtocolName());
} else if (allowSubActors && } else if (allowSubActors &&
IsManagedByTargetActor(protocol, protoIdFilter)) { IsManagedByTargetActor(protocol, protoIdFilter)) {
MOZ_FUZZING_NYX_PRINTF( MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
"INFO: [OnActorConnected] ActorID %d Protocol: %s is managed by " " Protocol: %s is managed by "
"target actor.\n", "target actor.\n",
protocol->Id(), protocol->GetProtocolName()); protocol->Id(), protocol->GetProtocolName());
} else { } else {
// Not a toplevel actor, not matching the filter and also either not a // Not a toplevel actor, not matching the filter and also either not a
// sub actor of our target or we are focusing only on the target. Ignore // sub actor of our target or we are focusing only on the target. Ignore
// this actor. // this actor.
if (!!getenv("MOZ_FUZZ_DEBUG")) { if (!!getenv("MOZ_FUZZ_DEBUG")) {
MOZ_FUZZING_NYX_PRINTF( MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
"INFO: [OnActorConnected] ActorID %d Protocol: %s ignored due to " " Protocol: %s ignored due to "
"filter.\n", "filter.\n",
protocol->Id(), protocol->GetProtocolName()); protocol->Id(), protocol->GetProtocolName());
} }
return; return;
} }
} }
if (!!getenv("MOZ_FUZZ_DEBUG")) { if (!!getenv("MOZ_FUZZ_DEBUG")) {
MOZ_FUZZING_NYX_PRINTF( MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64
"INFO: [OnActorConnected] ActorID %d Protocol: %s Port: %lu %lu\n", " Protocol: %s Port: %lu %lu\n",
protocol->Id(), protocol->GetProtocolName(), portName->v1, protocol->Id(), protocol->GetProtocolName(),
portName->v2); portName->v1, portName->v2);
} }
actorIds[*portName].emplace_back(protocol->Id(), protocol->GetProtocolId()); actorIds[*portName].emplace_back(protocol->Id(), protocol->GetProtocolId());
@@ -474,7 +475,8 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel,
} }
return true; return true;
} else if (aMessage.type() == mIPCTriggerMsg && !Nyx::instance().started()) { } else if (aMessage.type() == mIPCTriggerMsg && !Nyx::instance().started()) {
MOZ_FUZZING_NYX_PRINTF("DEBUG: Ready message detected on actor %d.\n", MOZ_FUZZING_NYX_PRINTF("DEBUG: Ready message detected on actor %" PRId64
".\n",
aMessage.routing_id()); aMessage.routing_id());
if (!haveTargetNodeName && !!getenv("MOZ_FUZZ_PROTOID_FILTER")) { if (!haveTargetNodeName && !!getenv("MOZ_FUZZ_PROTOID_FILTER")) {
@@ -504,7 +506,7 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel,
// In this mode, we really want to focus on a single actor. // In this mode, we really want to focus on a single actor.
useLastActor = 1024; useLastActor = 1024;
maybeLastActorId = aMessage.routing_id(); maybeLastActorId = aMessage.routing_id();
MOZ_FUZZING_NYX_PRINTF("DEBUG: Pinned to actor %d forever.\n", MOZ_FUZZING_NYX_PRINTF("DEBUG: Pinned to actor %" PRId64 " forever.\n",
aMessage.routing_id()); aMessage.routing_id());
} else { } else {
// In this mode, we want to focus on a particular actor and all of its // In this mode, we want to focus on a particular actor and all of its
@@ -644,8 +646,8 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel,
// Called on the I/O thread and modifies `portSeqNos`. // Called on the I/O thread and modifies `portSeqNos`.
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
portSeqNos.insert_or_assign( portSeqNos.insert_or_assign(
name, std::pair<int32_t, uint64_t>(aMessage.seqno(), name, std::pair<IPC::Message::seqno_t, uint64_t>(
userMsgEv->sequence_num())); aMessage.seqno(), userMsgEv->sequence_num()));
#ifdef FUZZ_DEBUG #ifdef FUZZ_DEBUG
MOZ_FUZZING_NYX_PRINTF( MOZ_FUZZING_NYX_PRINTF(
"DEBUG: Port %lu %lu updated sequence number to %lu\n", name.v1, "DEBUG: Port %lu %lu updated sequence number to %lu\n", name.v1,
@@ -718,8 +720,9 @@ void IPCFuzzController::OnMessageError(
bool IPCFuzzController::MakeTargetDecision( bool IPCFuzzController::MakeTargetDecision(
uint8_t portIndex, uint8_t portInstanceIndex, uint8_t actorIndex, uint8_t portIndex, uint8_t portInstanceIndex, uint8_t actorIndex,
uint8_t actorProtocolIndex, uint16_t typeOffset, PortName* name, uint8_t actorProtocolIndex, uint16_t typeOffset, PortName* name,
int32_t* seqno, uint64_t* fseqno, int32_t* actorId, uint32_t* type, IPC::Message::seqno_t* seqno, uint64_t* fseqno,
bool* is_cons, bool update) { mozilla::ipc::ActorId* actorId, uint32_t* type, bool* is_cons,
bool update) {
if (useLastActor) { if (useLastActor) {
useLastActor--; useLastActor--;
*name = lastActorPortName; *name = lastActorPortName;
@@ -894,14 +897,15 @@ bool IPCFuzzController::MakeTargetDecision(
MOZ_FUZZING_NYX_PRINTF( MOZ_FUZZING_NYX_PRINTF(
"DEBUG: MakeTargetDecision: Top-Level Protocol: %s Protocol: %s msgType: " "DEBUG: MakeTargetDecision: Top-Level Protocol: %s Protocol: %s msgType: "
"%s (%u), Actor Instance %u of %zu, actor ID: %d, PreservedHeader: %d\n", "%s (%u), Actor Instance %u of %zu, actor ID: %" PRId64
", PreservedHeader: %d\n",
portNameToProtocolName[*name].c_str(), ProtocolIdToName(ids.second), portNameToProtocolName[*name].c_str(), ProtocolIdToName(ids.second),
IPC::StringFromIPCMessageType(*type), *type, actorIndex, actors.size(), IPC::StringFromIPCMessageType(*type), *type, actorIndex, actors.size(),
*actorId, isPreserveHeader); *actorId, isPreserveHeader);
if (update) { if (update) {
portSeqNos.insert_or_assign(*name, portSeqNos.insert_or_assign(
std::pair<int32_t, uint64_t>(*seqno, *fseqno)); *name, std::pair<IPC::Message::seqno_t, uint64_t>(*seqno, *fseqno));
} }
return true; return true;
@@ -1048,7 +1052,7 @@ NS_IMETHODIMP IPCFuzzController::IPCFuzzLoop::Run() {
// have to adjust these so the next calculated sequence number pair // have to adjust these so the next calculated sequence number pair
// matches the start sequence numbers. // matches the start sequence numbers.
IPCFuzzController::instance().portSeqNos.insert_or_assign( IPCFuzzController::instance().portSeqNos.insert_or_assign(
iter->first, std::pair<int32_t, uint64_t>(0, 0)); iter->first, std::pair<IPC::Message::seqno_t, uint64_t>(0, 0));
IPCFuzzController::instance().AddToplevelActor( IPCFuzzController::instance().AddToplevelActor(
iter->first, iter->second[0].second); iter->first, iter->second[0].second);
@@ -1139,10 +1143,10 @@ NS_IMETHODIMP IPCFuzzController::IPCFuzzLoop::Run() {
ipchdr->payload_size = ipcMsgLen - sizeof(IPC::Message::Header); ipchdr->payload_size = ipcMsgLen - sizeof(IPC::Message::Header);
PortName new_port_name; PortName new_port_name;
int32_t new_seqno; IPC::Message::seqno_t new_seqno;
uint64_t new_fseqno; uint64_t new_fseqno;
int32_t actorId; mozilla::ipc::ActorId actorId;
uint32_t msgType = 0; uint32_t msgType = 0;
bool isConstructor = false; bool isConstructor = false;
// Control Data Layout (16 byte) // Control Data Layout (16 byte)
@@ -1575,7 +1579,7 @@ UniquePtr<IPC::Message> IPCFuzzController::replaceIPCMessage(
UniquePtr<IPC::Message> msg(new IPC::Message(ipcMsgData, ipcMsgLen)); UniquePtr<IPC::Message> msg(new IPC::Message(ipcMsgData, ipcMsgLen));
if (!!getenv("MOZ_FUZZ_DEBUG")) { if (!!getenv("MOZ_FUZZ_DEBUG")) {
MOZ_FUZZING_NYX_PRINTF("INFO: Name: %s Target: %d\n", msg->name(), MOZ_FUZZING_NYX_PRINTF("INFO: Name: %s Target: %" PRId64 "\n", msg->name(),
msg->routing_id()); msg->routing_id());
} }

View File

@@ -52,6 +52,7 @@ namespace ipc {
// We can't include ProtocolUtils.h here // We can't include ProtocolUtils.h here
class IProtocol; class IProtocol;
typedef IPCMessageStart ProtocolId; typedef IPCMessageStart ProtocolId;
typedef IPC::Message::routeid_t ActorId;
class NodeChannel; class NodeChannel;
} // namespace ipc } // namespace ipc
@@ -59,9 +60,10 @@ class NodeChannel;
namespace fuzzing { namespace fuzzing {
class IPCFuzzController { class IPCFuzzController {
typedef std::pair<int32_t, uint64_t> SeqNoPair; typedef std::pair<IPC::Message::seqno_t, uint64_t> SeqNoPair;
typedef std::pair<int32_t, mozilla::ipc::ProtocolId> ActorIdPair; typedef std::pair<mozilla::ipc::ActorId, mozilla::ipc::ProtocolId>
ActorIdPair;
class IPCFuzzLoop final : public Runnable { class IPCFuzzLoop final : public Runnable {
friend class IPCFuzzController; friend class IPCFuzzController;
@@ -87,8 +89,9 @@ class IPCFuzzController {
bool MakeTargetDecision(uint8_t portIndex, uint8_t portInstanceIndex, bool MakeTargetDecision(uint8_t portIndex, uint8_t portInstanceIndex,
uint8_t actorIndex, uint8_t actorProtocolIndex, uint8_t actorIndex, uint8_t actorProtocolIndex,
uint16_t typeOffset, uint16_t typeOffset,
mojo::core::ports::PortName* name, int32_t* seqno, mojo::core::ports::PortName* name,
uint64_t* fseqno, int32_t* actorId, uint32_t* type, IPC::Message::seqno_t* seqno, uint64_t* fseqno,
mozilla::ipc::ActorId* actorId, uint32_t* type,
bool* is_cons, bool update = true); bool* is_cons, bool update = true);
void OnActorConnected(mozilla::ipc::IProtocol* protocol); void OnActorConnected(mozilla::ipc::IProtocol* protocol);
@@ -159,7 +162,7 @@ class IPCFuzzController {
Atomic<uint32_t> useLastActor; Atomic<uint32_t> useLastActor;
// If this is non-zero, we want a specific actor ID instead of the last. // If this is non-zero, we want a specific actor ID instead of the last.
Atomic<int32_t> maybeLastActorId; Atomic<mozilla::ipc::ActorId> maybeLastActorId;
// If this is non-empty and in certain configurations, we only use a fixed // If this is non-empty and in certain configurations, we only use a fixed
// set of messages, rather than sending any message type for that actor. // set of messages, rather than sending any message type for that actor.

View File

@@ -596,7 +596,7 @@ template <>
void LogTaskBase<IPC::Message>::LogDispatchWithPid(IPC::Message* aEvent, void LogTaskBase<IPC::Message>::LogDispatchWithPid(IPC::Message* aEvent,
int32_t aPid) { int32_t aPid) {
if (aEvent->seqno() && aPid > 0) { if (aEvent->seqno() && aPid > 0) {
LOG1(("SEND %p %d %d", aEvent, aEvent->seqno(), aPid)); LOG1(("SEND %p %" PRId64 " %d", aEvent, aEvent->seqno(), aPid));
} }
} }
@@ -651,7 +651,7 @@ LogTaskBase<Task>::Run::Run(Task* aTask, bool aWillRunAgain)
template <> template <>
LogTaskBase<IPC::Message>::Run::Run(IPC::Message* aMessage, bool aWillRunAgain) LogTaskBase<IPC::Message>::Run::Run(IPC::Message* aMessage, bool aWillRunAgain)
: mWillRunAgain(aWillRunAgain) { : mWillRunAgain(aWillRunAgain) {
LOG1(("RECV %p %p %d [%s]", aMessage, this, aMessage->seqno(), LOG1(("RECV %p %p %" PRId64 " [%s]", aMessage, this, aMessage->seqno(),
aMessage->name())); aMessage->name()));
} }