From fc47f098e3892f6014b6fb49f082d79b79fd16c2 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 12 Jan 2011 01:07:17 -0600 Subject: [PATCH] Bug 572134: "Undefer" the in-call that lost a race at stack-depth 1, if there is one, when RPCChannel code leaves the C++ stack, so that the in-call can be processed if there is an immediately following out-call. r=bsmedberg --- ipc/glue/RPCChannel.cpp | 29 ++++++++++++----------------- ipc/glue/RPCChannel.h | 2 +- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/ipc/glue/RPCChannel.cpp b/ipc/glue/RPCChannel.cpp index 1f2ae232a641..87681c746e02 100644 --- a/ipc/glue/RPCChannel.cpp +++ b/ipc/glue/RPCChannel.cpp @@ -193,7 +193,7 @@ RPCChannel::Call(Message* msg, Message* reply) // now might be the time to process a message deferred because // of race resolution - MaybeProcessDeferredIncall(); + MaybeUndeferIncall(); // here we're waiting for something to happen. see long // comment about the queue in RPCChannel.h @@ -315,14 +315,14 @@ RPCChannel::Call(Message* msg, Message* reply) return true; } -bool -RPCChannel::MaybeProcessDeferredIncall() +void +RPCChannel::MaybeUndeferIncall() { AssertWorkerThread(); mMutex.AssertCurrentThreadOwns(); if (mDeferred.empty()) - return false; + return; size_t stackDepth = StackDepth(); @@ -331,9 +331,9 @@ RPCChannel::MaybeProcessDeferredIncall() "fatal logic error"); if (mDeferred.top().rpc_remote_stack_depth_guess() < stackDepth) - return false; + return; - // time to process this message + // maybe time to process this message Message call = mDeferred.top(); mDeferred.pop(); @@ -341,14 +341,7 @@ RPCChannel::MaybeProcessDeferredIncall() RPC_ASSERT(0 < mRemoteStackDepthGuess, "fatal logic error"); --mRemoteStackDepthGuess; - MutexAutoUnlock unlock(mMutex); - - if (LoggingEnabled()) - fprintf(stderr, " (processing deferred in-call)\n"); - - CxxStackFrame f(*this, IN_MESSAGE, &call); - Incall(call, stackDepth); - return true; + mPending.push(call); } void @@ -357,6 +350,8 @@ RPCChannel::EnqueuePendingMessages() AssertWorkerThread(); mMutex.AssertCurrentThreadOwns(); + MaybeUndeferIncall(); + for (size_t i = 0; i < mDeferred.size(); ++i) mWorkerLoop->PostTask( FROM_HERE, @@ -412,7 +407,7 @@ RPCChannel::OnMaybeDequeueOne() } if (!mDeferred.empty()) - return MaybeProcessDeferredIncall(); + MaybeUndeferIncall(); if (mPending.empty()) return false; @@ -482,8 +477,8 @@ RPCChannel::Incall(const Message& call, size_t stackDepth) } if (LoggingEnabled()) { - fprintf(stderr, " (%s won, so we're%sdeferring)\n", - winner, defer ? " " : " not "); + fprintf(stderr, " (%s: %s won, so we're%sdeferring)\n", + mChild ? "child" : "parent", winner, defer ? " " : " not "); } if (defer) { diff --git a/ipc/glue/RPCChannel.h b/ipc/glue/RPCChannel.h index 86be780e72fa..b9a9b053302d 100644 --- a/ipc/glue/RPCChannel.h +++ b/ipc/glue/RPCChannel.h @@ -198,7 +198,7 @@ protected: bool EventOccurred() const; - bool MaybeProcessDeferredIncall(); + void MaybeUndeferIncall(); void EnqueuePendingMessages(); /**