Bug 549888: Part 1: Let the channel listener decide how to mediate RPC races, defaulting to "child wins". r=bent

This commit is contained in:
Chris Jones 2010-03-11 01:35:30 -06:00
Родитель 407c6ae670
Коммит c9b2213be5
3 изменённых файлов: 26 добавлений и 19 удалений

Просмотреть файл

@ -89,15 +89,13 @@ public:
namespace mozilla {
namespace ipc {
RPCChannel::RPCChannel(RPCListener* aListener,
RacyRPCPolicy aPolicy)
RPCChannel::RPCChannel(RPCListener* aListener)
: SyncChannel(aListener),
mPending(),
mStack(),
mOutOfTurnReplies(),
mDeferred(),
mRemoteStackDepthGuess(0),
mRacePolicy(aPolicy),
mBlockedOnParent(false),
mCxxStackFrames(0)
{
@ -422,7 +420,8 @@ RPCChannel::Incall(const Message& call, size_t stackDepth)
// the other side's in-call
bool defer;
const char* winner;
switch (mRacePolicy) {
switch (Listener()->MediateRPCRace(mChild ? call : mStack.top(),
mChild ? mStack.top() : call)) {
case RRPChildWins:
winner = "child";
defer = mChild;
@ -470,8 +469,7 @@ RPCChannel::DispatchIncall(const Message& call)
Message* reply = nsnull;
++mRemoteStackDepthGuess;
Result rv =
static_cast<RPCListener*>(mListener)->OnCallReceived(call, reply);
Result rv = Listener()->OnCallReceived(call, reply);
--mRemoteStackDepthGuess;
if (!MaybeHandleError(rv, "RPCChannel")) {

Просмотреть файл

@ -55,6 +55,13 @@ class RPCChannel : public SyncChannel
friend class CxxStackFrame;
public:
// What happens if RPC calls race?
enum RacyRPCPolicy {
RRPError,
RRPChildWins,
RRPParentWins
};
class /*NS_INTERFACE_CLASS*/ RPCListener :
public SyncChannel::SyncListener
{
@ -78,17 +85,16 @@ public:
virtual void OnExitedCxxStack()
{
NS_RUNTIMEABORT("default impl shouldn't be invoked");
}
}
virtual RacyRPCPolicy MediateRPCRace(const Message& parent,
const Message& child)
{
return RRPChildWins;
}
};
// What happens if RPC calls race?
enum RacyRPCPolicy {
RRPError,
RRPChildWins,
RRPParentWins
};
RPCChannel(RPCListener* aListener, RacyRPCPolicy aPolicy=RRPChildWins);
RPCChannel(RPCListener* aListener);
virtual ~RPCChannel();
@ -167,6 +173,10 @@ protected:
private:
// Called on worker thread only
RPCListener* Listener() const {
return static_cast<RPCListener*>(mListener);
}
bool EventOccurred();
void MaybeProcessDeferredIncall();
@ -185,12 +195,12 @@ protected:
// for when the depth goes from non-zero to zero;
void EnteredCxxStack()
{
static_cast<RPCListener*>(mListener)->OnEnteredCxxStack();
Listener()->OnEnteredCxxStack();
}
void ExitedCxxStack()
{
static_cast<RPCListener*>(mListener)->OnExitedCxxStack();
Listener()->OnExitedCxxStack();
}
class NS_STACK_CLASS CxxStackFrame
@ -327,7 +337,6 @@ protected:
// detect the same race.
//
size_t mRemoteStackDepthGuess;
RacyRPCPolicy mRacePolicy;
// True iff the parent has put us in a |BlockChild()| state.
bool mBlockedOnParent;

Просмотреть файл

@ -2662,7 +2662,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
Whitespace.NL ])
self.cls.addstmts((
[ Label.PRIVATE ]
[ Label.PUBLIC ]
+ self.standardTypedefs()
+ [ Whitespace.NL ]
))