Skip to content

Commit

Permalink
Bug 1451363 - part 2b - move protocol event target access into Protoc…
Browse files Browse the repository at this point in the history
…olState; r=mccr8

The reasoning here is the same as for the protocol register/lookup
functions: these functions are all basic functionality that should not
be overriden by subclasses.
  • Loading branch information
froydnj committed Apr 23, 2018
1 parent f87dd10 commit 7f5404a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 64 deletions.
74 changes: 41 additions & 33 deletions ipc/glue/ProtocolUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ IProtocol::SetEventTargetForActor(IProtocol* aActor, nsIEventTarget* aEventTarge
{
// Make sure we have a manager for the internal method to access.
aActor->SetManager(this);
SetEventTargetForActorInternal(aActor, aEventTarget);
mState->SetEventTargetForActor(aActor, aEventTarget);
}

void
Expand All @@ -543,46 +543,59 @@ IProtocol::ReplaceEventTargetForActor(IProtocol* aActor,
{
// Ensure the actor has been registered.
MOZ_ASSERT(aActor->Manager());
ReplaceEventTargetForActorInternal(aActor, aEventTarget);
mState->ReplaceEventTargetForActor(aActor, aEventTarget);
}

void
IProtocol::SetEventTargetForActorInternal(IProtocol* aActor,
nsIEventTarget* aEventTarget)
nsIEventTarget*
IProtocol::GetActorEventTarget()
{
Manager()->SetEventTargetForActorInternal(aActor, aEventTarget);
return mState->GetActorEventTarget();
}

void
IProtocol::ReplaceEventTargetForActorInternal(IProtocol* aActor,
nsIEventTarget* aEventTarget)
already_AddRefed<nsIEventTarget>
IProtocol::GetActorEventTarget(IProtocol* aActor)
{
Manager()->ReplaceEventTargetForActorInternal(aActor, aEventTarget);
return mState->GetActorEventTarget(aActor);
}

nsIEventTarget*
IProtocol::GetActorEventTarget()
IProtocol::ManagedState::GetActorEventTarget()
{
// We should only call this function when this actor has been registered and
// is not unregistered yet.
MOZ_RELEASE_ASSERT(mId != kNullActorId && mId != kFreedActorId);
RefPtr<nsIEventTarget> target = Manager()->GetActorEventTargetInternal(this);
MOZ_RELEASE_ASSERT(mProtocol->mId != kNullActorId && mProtocol->mId != kFreedActorId);
RefPtr<nsIEventTarget> target = GetActorEventTarget(mProtocol);
return target;
}

void
IProtocol::ManagedState::SetEventTargetForActor(IProtocol* aActor,
nsIEventTarget* aEventTarget)
{
// Go directly through the state so we don't try to redundantly (and
// wrongly) call SetManager() on aActor.
mProtocol->Manager()->mState->SetEventTargetForActor(aActor, aEventTarget);
}

void
IProtocol::ManagedState::ReplaceEventTargetForActor(IProtocol* aActor,
nsIEventTarget* aEventTarget)
{
mProtocol->Manager()->ReplaceEventTargetForActor(aActor, aEventTarget);
}

already_AddRefed<nsIEventTarget>
IProtocol::GetActorEventTargetInternal(IProtocol* aActor)
IProtocol::ManagedState::GetActorEventTarget(IProtocol* aActor)
{
return Manager()->GetActorEventTargetInternal(aActor);
return mProtocol->Manager()->GetActorEventTarget(aActor);
}

IToplevelProtocol::IToplevelProtocol(ProtocolId aProtoId, Side aSide)
: IProtocol(aSide, MakeUnique<ToplevelState>(this, aSide)),
mMonitor("mozilla.ipc.IToplevelProtocol.mMonitor"),
mProtocolId(aProtoId),
mOtherPid(mozilla::ipc::kInvalidProcessId),
mOtherPidState(ProcessIdState::eUnstarted),
mEventTargetMutex("ProtocolEventTargetMutex")
mOtherPidState(ProcessIdState::eUnstarted)
{
}

Expand Down Expand Up @@ -742,6 +755,7 @@ IToplevelProtocol::ToplevelState::ToplevelState(IToplevelProtocol* aProtocol, Si
: mProtocol(aProtocol)
, mLastRouteId(aSide == ParentSide ? kFreedActorId : kNullActorId)
, mLastShmemId(aSide == ParentSide ? kFreedActorId : kNullActorId)
, mEventTargetMutex("ProtocolEventTargetMutex")
{
}

Expand Down Expand Up @@ -862,7 +876,7 @@ IToplevelProtocol::ToplevelState::ShmemDestroyed(const Message& aMsg)
}

already_AddRefed<nsIEventTarget>
IToplevelProtocol::GetMessageEventTarget(const Message& aMsg)
IToplevelProtocol::ToplevelState::GetMessageEventTarget(const Message& aMsg)
{
int32_t route = aMsg.routing_id();

Expand All @@ -883,22 +897,22 @@ IToplevelProtocol::GetMessageEventTarget(const Message& aMsg)
// one.
if (!target) {
MutexAutoUnlock unlock(mEventTargetMutex);
target = GetConstructedEventTarget(aMsg);
target = mProtocol->GetConstructedEventTarget(aMsg);
}

mEventTargetMap.AddWithID(target, handle.mId);
} else if (!target) {
// We don't need the lock after this point.
lock.reset();

target = GetSpecificMessageEventTarget(aMsg);
target = mProtocol->GetSpecificMessageEventTarget(aMsg);
}

return target.forget();
}

already_AddRefed<nsIEventTarget>
IToplevelProtocol::GetActorEventTargetInternal(IProtocol* aActor)
IToplevelProtocol::ToplevelState::GetActorEventTarget(IProtocol* aActor)
{
MOZ_RELEASE_ASSERT(aActor->Id() != kNullActorId && aActor->Id() != kFreedActorId);

Expand All @@ -907,25 +921,19 @@ IToplevelProtocol::GetActorEventTargetInternal(IProtocol* aActor)
return target.forget();
}

already_AddRefed<nsIEventTarget>
IToplevelProtocol::GetActorEventTarget(IProtocol* aActor)
{
return GetActorEventTargetInternal(aActor);
}

nsIEventTarget*
IToplevelProtocol::GetActorEventTarget()
IToplevelProtocol::ToplevelState::GetActorEventTarget()
{
// The EventTarget of a ToplevelProtocol shall never be set.
return nullptr;
}

void
IToplevelProtocol::SetEventTargetForActorInternal(IProtocol* aActor,
nsIEventTarget* aEventTarget)
IToplevelProtocol::ToplevelState::SetEventTargetForActor(IProtocol* aActor,
nsIEventTarget* aEventTarget)
{
// The EventTarget of a ToplevelProtocol shall never be set.
MOZ_RELEASE_ASSERT(aActor != this);
MOZ_RELEASE_ASSERT(aActor != mProtocol);

// We should only call this function on actors that haven't been used for IPC
// code yet. Otherwise we'll be posting stuff to the wrong event target before
Expand All @@ -952,12 +960,12 @@ IToplevelProtocol::SetEventTargetForActorInternal(IProtocol* aActor,
}

void
IToplevelProtocol::ReplaceEventTargetForActorInternal(
IToplevelProtocol::ToplevelState::ReplaceEventTargetForActor(
IProtocol* aActor,
nsIEventTarget* aEventTarget)
{
// The EventTarget of a ToplevelProtocol shall never be set.
MOZ_RELEASE_ASSERT(aActor != this);
MOZ_RELEASE_ASSERT(aActor != mProtocol);

int32_t id = aActor->Id();
// The ID of the actor should have existed.
Expand Down
64 changes: 33 additions & 31 deletions ipc/glue/ProtocolUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ class IProtocol : public HasResultCodes
virtual int32_t RegisterID(IProtocol*, int32_t) = 0;
virtual IProtocol* Lookup(int32_t) = 0;
virtual void Unregister(int32_t) = 0;

// Returns the event target set by SetEventTargetForActor() if available.
virtual nsIEventTarget* GetActorEventTarget() = 0;

virtual void SetEventTargetForActor(IProtocol* aActor, nsIEventTarget* aEventTarget) = 0;
virtual void ReplaceEventTargetForActor(IProtocol* aActor, nsIEventTarget* aEventTarget) = 0;

virtual already_AddRefed<nsIEventTarget>
GetActorEventTarget(IProtocol* aActor) = 0;
};

// Managed protocols just forward all of their operations to the topmost
Expand All @@ -195,6 +204,11 @@ class IProtocol : public HasResultCodes
IProtocol* Lookup(int32_t) override;
void Unregister(int32_t) override;

nsIEventTarget* GetActorEventTarget() override;
void SetEventTargetForActor(IProtocol* aActor, nsIEventTarget* aEventTarget) override;
void ReplaceEventTargetForActor(IProtocol* aActor, nsIEventTarget* aEventTarget) override;
already_AddRefed<nsIEventTarget> GetActorEventTarget(IProtocol* aActor) override;

private:
IProtocol* const mProtocol;
};
Expand Down Expand Up @@ -284,8 +298,8 @@ class IProtocol : public HasResultCodes
void ReplaceEventTargetForActor(IProtocol* aActor,
nsIEventTarget* aEventTarget);

// Returns the event target set by SetEventTargetForActor() if available.
virtual nsIEventTarget* GetActorEventTarget();
nsIEventTarget* GetActorEventTarget();
already_AddRefed<nsIEventTarget> GetActorEventTarget(IProtocol* aActor);

protected:
IProtocol(Side aSide, UniquePtr<ProtocolState> aState)
Expand All @@ -303,14 +317,6 @@ class IProtocol : public HasResultCodes
void SetManager(IProtocol* aManager);
void SetIPCChannel(MessageChannel* aChannel) { mChannel = aChannel; }

virtual void SetEventTargetForActorInternal(IProtocol* aActor, nsIEventTarget* aEventTarget);
virtual void ReplaceEventTargetForActorInternal(
IProtocol* aActor,
nsIEventTarget* aEventTarget);

virtual already_AddRefed<nsIEventTarget>
GetActorEventTargetInternal(IProtocol* aActor);

static const int32_t kNullActorId = 0;
static const int32_t kFreedActorId = 1;

Expand Down Expand Up @@ -390,12 +396,23 @@ class IToplevelProtocol : public IProtocol
IProtocol* Lookup(int32_t) override;
void Unregister(int32_t) override;

nsIEventTarget* GetActorEventTarget() override;
void SetEventTargetForActor(IProtocol* aActor, nsIEventTarget* aEventTarget) override;
void ReplaceEventTargetForActor(IProtocol* aActor, nsIEventTarget* aEventTarget) override;
already_AddRefed<nsIEventTarget> GetActorEventTarget(IProtocol* aActor) override;

virtual already_AddRefed<nsIEventTarget>
GetMessageEventTarget(const Message& aMsg);

private:
IToplevelProtocol* const mProtocol;
IDMap<IProtocol*> mActorMap;
int32_t mLastRouteId;
IDMap<Shmem::SharedMemory*> mShmemMap;
Shmem::id_t mLastShmemId;

Mutex mEventTargetMutex;
IDMap<nsCOMPtr<nsIEventTarget>> mEventTargetMap;
};

using SchedulerGroupSet = nsILabelableRunnable::SchedulerGroupSet;
Expand Down Expand Up @@ -519,20 +536,17 @@ class IToplevelProtocol : public IProtocol
return false;
}

virtual already_AddRefed<nsIEventTarget>
GetMessageEventTarget(const Message& aMsg);

already_AddRefed<nsIEventTarget>
GetActorEventTarget(IProtocol* aActor);

virtual nsIEventTarget*
GetActorEventTarget() override;

virtual void OnChannelReceivedMessage(const Message& aMsg) {}

bool IsMainThreadProtocol() const { return mIsMainThreadProtocol; }
void SetIsMainThreadProtocol() { mIsMainThreadProtocol = NS_IsMainThread(); }

already_AddRefed<nsIEventTarget>
GetMessageEventTarget(const Message& aMsg)
{
return DowncastState()->GetMessageEventTarget(aMsg);
}

protected:
ToplevelState* DowncastState() const
{
Expand All @@ -549,15 +563,6 @@ class IToplevelProtocol : public IProtocol
virtual already_AddRefed<nsIEventTarget>
GetSpecificMessageEventTarget(const Message& aMsg) { return nullptr; }

virtual void SetEventTargetForActorInternal(IProtocol* aActor,
nsIEventTarget* aEventTarget) override;
virtual void ReplaceEventTargetForActorInternal(
IProtocol* aActor,
nsIEventTarget* aEventTarget) override;

virtual already_AddRefed<nsIEventTarget>
GetActorEventTargetInternal(IProtocol* aActor) override;

// This monitor protects mOtherPid and mOtherPidState. All other fields
// should only be accessed on the worker thread.
mutable mozilla::Monitor mMonitor;
Expand All @@ -569,9 +574,6 @@ class IToplevelProtocol : public IProtocol
base::ProcessId mOtherPid;
ProcessIdState mOtherPidState;
bool mIsMainThreadProtocol;

Mutex mEventTargetMutex;
IDMap<nsCOMPtr<nsIEventTarget>> mEventTargetMap;
};

class IShmemAllocator
Expand Down

0 comments on commit 7f5404a

Please sign in to comment.