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:
committed by
rvandermeulen@mozilla.com
parent
2b681a7411
commit
31a3ea2fb1
14
dom/cache/Manager.cpp
vendored
14
dom/cache/Manager.cpp
vendored
@@ -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
5
dom/cache/Manager.h
vendored
@@ -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:
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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.");
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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__();
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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__
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 =
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 <>
|
||||||
|
|||||||
@@ -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
|
IProtocol* IToplevelProtocol::Lookup(ActorId aId) {
|
||||||
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) {
|
|
||||||
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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
|
||||||
->ReadActor(${readervar}, true, ${actortype}, ${protocolid});
|
|
||||||
if (actor.isSome()) {
|
|
||||||
return static_cast<${cxxtype}>(actor.ref());
|
|
||||||
}
|
|
||||||
return {};
|
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,11 +4823,11 @@ 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]),
|
||||||
@@ -4860,20 +4836,32 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||||||
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(
|
||||||
|
None,
|
||||||
|
_actorId(ExprVar("actor")),
|
||||||
|
ExprAddrOf(writervar),
|
||||||
|
sentinelKey="actorid",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
start = 1
|
||||||
|
|
||||||
|
stmts += [
|
||||||
_ParamTraits.checkedWrite(
|
_ParamTraits.checkedWrite(
|
||||||
p.ipdltype,
|
p.ipdltype,
|
||||||
p.var(),
|
p.var(),
|
||||||
ExprAddrOf(writervar),
|
ExprAddrOf(writervar),
|
||||||
sentinelKey=p.name,
|
sentinelKey=p.name,
|
||||||
)
|
)
|
||||||
for p in md.params
|
for p in md.params[start:]
|
||||||
]
|
]
|
||||||
+ [Whitespace.NL]
|
|
||||||
+ self.setMessageFlags(md, msgvar)
|
|
||||||
)
|
|
||||||
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, []
|
|
||||||
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 = [
|
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)])
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -326,15 +326,16 @@ 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());
|
||||||
|
|
||||||
@@ -343,14 +344,14 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
|
|||||||
// 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 {
|
||||||
@@ -358,8 +359,8 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
|
|||||||
// 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());
|
||||||
}
|
}
|
||||||
@@ -368,10 +369,10 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user