Bug 1177013 - Change IPC locking to get transaction ID correct (r=dvander)

This commit is contained in:
Bill McCloskey 2015-06-30 14:48:29 -07:00
parent 7b8c6bd586
commit 5a6551cf28
2 changed files with 34 additions and 46 deletions

View File

@ -974,12 +974,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
// If the message is not Interrupt, we can dispatch it as normal. // If the message is not Interrupt, we can dispatch it as normal.
if (!recvd.is_interrupt()) { if (!recvd.is_interrupt()) {
{
AutoEnterTransaction transaction(this, recvd);
MonitorAutoUnlock unlock(*mMonitor);
CxxStackFrame frame(*this, IN_MESSAGE, &recvd);
DispatchMessage(recvd); DispatchMessage(recvd);
}
if (!Connected()) { if (!Connected()) {
ReportConnectionError("MessageChannel::DispatchMessage"); ReportConnectionError("MessageChannel::DispatchMessage");
return false; return false;
@ -1107,14 +1102,7 @@ MessageChannel::ProcessPendingRequest(const Message &aUrgent)
// to save the reply. // to save the reply.
nsAutoPtr<Message> savedReply(mRecvd.forget()); nsAutoPtr<Message> savedReply(mRecvd.forget());
{
// In order to send the parent RPC messages and guarantee it will
// wake up, we must re-use its transaction.
AutoEnterTransaction transaction(this, aUrgent);
MonitorAutoUnlock unlock(*mMonitor);
DispatchMessage(aUrgent); DispatchMessage(aUrgent);
}
if (!Connected()) { if (!Connected()) {
ReportConnectionError("MessageChannel::ProcessPendingRequest"); ReportConnectionError("MessageChannel::ProcessPendingRequest");
return false; return false;
@ -1171,16 +1159,10 @@ MessageChannel::OnMaybeDequeueOne()
return false; return false;
} }
{
// We should not be in a transaction yet if we're not blocked. // We should not be in a transaction yet if we're not blocked.
MOZ_ASSERT(mCurrentTransaction == 0); MOZ_ASSERT(mCurrentTransaction == 0);
AutoEnterTransaction transaction(this, recvd);
MonitorAutoUnlock unlock(*mMonitor);
CxxStackFrame frame(*this, IN_MESSAGE, &recvd);
DispatchMessage(recvd); DispatchMessage(recvd);
}
return true; return true;
} }
@ -1190,21 +1172,32 @@ MessageChannel::DispatchMessage(const Message &aMsg)
Maybe<AutoNoJSAPI> nojsapi; Maybe<AutoNoJSAPI> nojsapi;
if (ScriptSettingsInitialized() && NS_IsMainThread()) if (ScriptSettingsInitialized() && NS_IsMainThread())
nojsapi.emplace(); nojsapi.emplace();
nsAutoPtr<Message> reply;
{
AutoEnterTransaction transaction(this, aMsg);
MonitorAutoUnlock unlock(*mMonitor);
CxxStackFrame frame(*this, IN_MESSAGE, &aMsg);
if (aMsg.is_sync()) if (aMsg.is_sync())
DispatchSyncMessage(aMsg); DispatchSyncMessage(aMsg, *getter_Transfers(reply));
else if (aMsg.is_interrupt()) else if (aMsg.is_interrupt())
DispatchInterruptMessage(aMsg, 0); DispatchInterruptMessage(aMsg, 0);
else else
DispatchAsyncMessage(aMsg); DispatchAsyncMessage(aMsg);
}
if (reply && ChannelConnected == mChannelState) {
mLink->SendMessage(reply.forget());
}
} }
void void
MessageChannel::DispatchSyncMessage(const Message& aMsg) MessageChannel::DispatchSyncMessage(const Message& aMsg, Message*& aReply)
{ {
AssertWorkerThread(); AssertWorkerThread();
nsAutoPtr<Message> reply;
int prio = aMsg.priority(); int prio = aMsg.priority();
// We don't want to run any code that might run a nested event loop here, so // We don't want to run any code that might run a nested event loop here, so
@ -1242,23 +1235,18 @@ MessageChannel::DispatchSyncMessage(const Message& aMsg)
AutoSetValue<bool> blocked(blockingVar, true); AutoSetValue<bool> blocked(blockingVar, true);
AutoSetValue<bool> sync(mDispatchingSyncMessage, true); AutoSetValue<bool> sync(mDispatchingSyncMessage, true);
AutoSetValue<int> prioSet(mDispatchingSyncMessagePriority, prio); AutoSetValue<int> prioSet(mDispatchingSyncMessagePriority, prio);
rv = mListener->OnMessageReceived(aMsg, *getter_Transfers(reply)); rv = mListener->OnMessageReceived(aMsg, aReply);
} }
if (!MaybeHandleError(rv, aMsg, "DispatchSyncMessage")) { if (!MaybeHandleError(rv, aMsg, "DispatchSyncMessage")) {
reply = new Message(); aReply = new Message();
reply->set_sync(); aReply->set_sync();
reply->set_priority(aMsg.priority()); aReply->set_priority(aMsg.priority());
reply->set_reply(); aReply->set_reply();
reply->set_reply_error(); aReply->set_reply_error();
}
reply->set_seqno(aMsg.seqno());
reply->set_transaction_id(aMsg.transaction_id());
MonitorAutoLock lock(*mMonitor);
if (ChannelConnected == mChannelState) {
mLink->SendMessage(reply.forget());
} }
aReply->set_seqno(aMsg.seqno());
aReply->set_transaction_id(aMsg.transaction_id());
} }
void void

View File

@ -242,7 +242,7 @@ class MessageChannel : HasResultCodes
// DispatchMessage will route to one of these functions depending on the // DispatchMessage will route to one of these functions depending on the
// protocol type of the message. // protocol type of the message.
void DispatchSyncMessage(const Message &aMsg); void DispatchSyncMessage(const Message &aMsg, Message*& aReply);
void DispatchUrgentMessage(const Message &aMsg); void DispatchUrgentMessage(const Message &aMsg);
void DispatchAsyncMessage(const Message &aMsg); void DispatchAsyncMessage(const Message &aMsg);
void DispatchRPCMessage(const Message &aMsg); void DispatchRPCMessage(const Message &aMsg);