зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
407c6ae670
Коммит
c9b2213be5
|
@ -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 ]
|
||||
))
|
||||
|
|
Загрузка…
Ссылка в новой задаче