Bug 1240985 - Check for cancellation during ProcessPendingRequests (r=dvander)

This commit is contained in:
Bill McCloskey 2016-01-19 17:34:31 -08:00
Родитель 6adb2b6441
Коммит adab8ac1e6
2 изменённых файлов: 32 добавлений и 5 удалений

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

@ -793,15 +793,25 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
}
void
MessageChannel::ProcessPendingRequests()
MessageChannel::ProcessPendingRequests(int transaction, int prio)
{
IPC_LOG("ProcessPendingRequests");
// Loop until there aren't any more priority messages to process.
for (;;) {
mozilla::Vector<Message> toProcess;
for (MessageQueue::iterator it = mPending.begin(); it != mPending.end(); ) {
Message &msg = *it;
if (!ShouldDeferMessage(msg)) {
bool defer = ShouldDeferMessage(msg);
// Only log the interesting messages.
if (msg.is_sync() || msg.priority() == IPC::Message::PRIORITY_URGENT) {
IPC_LOG("ShouldDeferMessage(seqno=%d) = %d", msg.seqno(), defer);
}
if (!defer) {
if (!toProcess.append(Move(msg)))
MOZ_CRASH();
it = mPending.erase(it);
@ -815,8 +825,18 @@ MessageChannel::ProcessPendingRequests()
// Processing these messages could result in more messages, so we
// loop around to check for more afterwards.
for (auto it = toProcess.begin(); it != toProcess.end(); it++)
ProcessPendingRequest(*it);
// If we canceled during ProcessPendingRequest, then we need to leave
// immediately because the results of ShouldDeferMessage will be
// operating with weird state (as if no Send is in progress). That could
// cause even normal priority sync messages to be processed (but not
// normal priority async messages), which would break message ordering.
if (WasTransactionCanceled(transaction, prio)) {
return;
}
}
}
@ -939,8 +959,11 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
int32_t transaction = mCurrentTransaction;
msg->set_transaction_id(transaction);
ProcessPendingRequests();
IPC_LOG("Send seqno=%d, xid=%d", seqno, transaction);
ProcessPendingRequests(transaction, prio);
if (WasTransactionCanceled(transaction, prio)) {
IPC_LOG("Other side canceled seqno=%d, xid=%d", seqno, transaction);
return false;
}
@ -948,23 +971,27 @@ MessageChannel::Send(Message* aMsg, Message* aReply)
mLink->SendMessage(msg.forget());
while (true) {
ProcessPendingRequests();
ProcessPendingRequests(transaction, prio);
if (WasTransactionCanceled(transaction, prio)) {
IPC_LOG("Other side canceled seqno=%d, xid=%d", seqno, transaction);
return false;
}
// See if we've received a reply.
if (mRecvdErrors) {
IPC_LOG("Error: seqno=%d, xid=%d", seqno, transaction);
mRecvdErrors--;
return false;
}
if (mRecvd) {
IPC_LOG("Got reply: seqno=%d, xid=%d", seqno, transaction);
break;
}
MOZ_ASSERT(!mTimedOutMessageSeqno);
MOZ_ASSERT(mCurrentTransaction == transaction);
bool maybeTimedOut = !WaitForSyncNotify(handleWindowsMessages);
if (!Connected()) {

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

@ -250,7 +250,7 @@ class MessageChannel : HasResultCodes
bool InterruptEventOccurred();
bool HasPendingEvents();
void ProcessPendingRequests();
void ProcessPendingRequests(int transaction, int prio);
bool ProcessPendingRequest(const Message &aUrgent);
void MaybeUndeferIncall();