Bug 1130051 - Restore old semantics of IPDL 'compress' attribute. r=billm
authorDavid Parks <davidp99@gmail.com>
Thu, 12 Feb 2015 12:32:03 -0800
changeset 243037 416a3c508df259ff475257e85ea6a6c1cb93a464
parent 243036 143174851bb7f0a2ef6501b48cfabfe382abb4ec
child 243038 5931982fa54bd923b75658713367a2ef06b1bd51
push id696
push userjoshua.m.grant@gmail.com
push dateMon, 16 Feb 2015 15:36:51 +0000
reviewersbillm
bugs1130051, 1076820
milestone38.0a1
Bug 1130051 - Restore old semantics of IPDL 'compress' attribute. r=billm In bug 1076820, the semantics of the IPDL 'compress' attribute were changed to remove *all* duplicate messages of a type from the IPDL message queue. This restores the original behavior, where duplicates were only removed if they were adjacent in the message queue.
ipc/glue/MessageChannel.cpp
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -601,29 +601,16 @@ MessageChannel::ShouldDeferMessage(const
     //
     // Deferring in the parent only sort of breaks message ordering. When the
     // child's message comes in, we can pretend the child hasn't quite
     // finished sending it yet. Since the message is sync, we know that the
     // child hasn't moved on yet.
     return mSide == ParentSide && aMsg.transaction_id() != mCurrentTransaction;
 }
 
-// Predicate that is true for messages that should be consolidated if 'compress' is set.
-class MatchingKinds {
-    typedef IPC::Message Message;
-    Message::msgid_t mType;
-    int32_t mRoutingId;
-public:
-    MatchingKinds(Message::msgid_t aType, int32_t aRoutingId) :
-        mType(aType), mRoutingId(aRoutingId) {}
-    bool operator()(const Message &msg) {
-        return msg.type() == mType && msg.routing_id() == mRoutingId;
-    }
-};
-
 void
 MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
 {
     AssertLinkThread();
     mMonitor->AssertCurrentThreadOwns();
 
     if (MaybeInterceptSpecialIOMessage(aMsg))
         return;
@@ -657,32 +644,25 @@ MessageChannel::OnMessageReceivedFromLin
         mRecvd = new Message(aMsg);
         NotifyWorkerThread();
         return;
     }
 
     // Prioritized messages cannot be compressed.
     MOZ_ASSERT(!aMsg.compress() || aMsg.priority() == IPC::Message::PRIORITY_NORMAL);
 
-    bool compress = (aMsg.compress() && !mPending.empty());
+    bool compress = (aMsg.compress() && !mPending.empty() &&
+                     mPending.back().type() == aMsg.type() &&
+                     mPending.back().routing_id() == aMsg.routing_id());
     if (compress) {
-        // Check the message queue for another message with this type/destination.
-        auto it = std::find_if(mPending.rbegin(), mPending.rend(),
-                               MatchingKinds(aMsg.type(), aMsg.routing_id()));
-        if (it != mPending.rend()) {
-            // This message type has compression enabled, and the queue holds
-            // a message with the same message type and routed to the same destination.
-            // Erase it.  Note that, since we always compress these redundancies, There Can
-            // Be Only One.
-            MOZ_ASSERT((*it).compress());
-            mPending.erase((++it).base());
-        } else {
-            // No other messages with the same type/destination exist.
-            compress = false;
-        }
+        // This message type has compression enabled, and the back of the
+        // queue was the same message type and routed to the same destination.
+        // Replace it with the newer message.
+        MOZ_ASSERT(mPending.back().compress());
+        mPending.pop_back();
     }
 
     bool shouldWakeUp = AwaitingInterruptReply() ||
                         (AwaitingSyncReply() && !ShouldDeferMessage(aMsg)) ||
                         AwaitingIncomingMessage();
 
     // There are three cases we're concerned about, relating to the state of the
     // main thread: