From b15d1dec183feb4ea3efb38adcddf1860a0041ec Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 20 Jan 2010 21:50:36 -0600 Subject: [PATCH] Bug 538239: Guard against async messages unblocking sync message waits. r=bent --HG-- extra : transplant_source : .%3E%14%26%12%B1%80%BC%60%5D%E5%27%DE%11%C6uRY%F36 --- ipc/glue/SyncChannel.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ipc/glue/SyncChannel.cpp b/ipc/glue/SyncChannel.cpp index 22654dd3d31..77e89e7ea15 100644 --- a/ipc/glue/SyncChannel.cpp +++ b/ipc/glue/SyncChannel.cpp @@ -93,8 +93,16 @@ SyncChannel::Send(Message* msg, Message* reply) FROM_HERE, NewRunnableMethod(this, &SyncChannel::OnSend, msg)); - // wait for the next sync message to arrive - WaitForNotify(); + // NB: this is a do-while loop instead of a single wait because if + // there's a pending RPC out- or in-call below us, and the sync + // message handler on the other side sends us an async message, + // the IO thread will Notify() this thread of the async message. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=538239. + do { + // wait for the next sync message to arrive + WaitForNotify(); + } while(Connected() && + mPendingReply != mRecvd.type() && !mRecvd.is_reply_error()); if (!Connected()) { ReportConnectionError("SyncChannel"); @@ -109,11 +117,13 @@ SyncChannel::Send(Message* msg, Message* reply) // FIXME/cjones: real error handling NS_ABORT_IF_FALSE(mRecvd.is_sync() && mRecvd.is_reply() && - (mPendingReply == mRecvd.type() || mRecvd.is_reply_error()), + (mPendingReply == mRecvd.type() || + mRecvd.is_reply_error()), "unexpected sync message"); mPendingReply = 0; *reply = mRecvd; + mRecvd = Message(); return true; }