Bug 811596 - Shrink the IPC message buffer after each message is processed. r=cjones, a=akeybl
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 19 Nov 2012 20:52:44 -0800
changeset 117047 0e1c415ec2efefff2c2ec230cb099676402d4aa1
parent 117046 464cf04f7f866f5d0628e0cc237f4f942a0f0d6e
child 117048 8f0032f484977a74528d3eafe7193f1375e29252
push id1729
push userryanvm@gmail.com
push dateWed, 21 Nov 2012 22:39:15 +0000
treeherdermozilla-beta@8f0032f48497 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones, akeybl
bugs811596
milestone18.0
Bug 811596 - Shrink the IPC message buffer after each message is processed. r=cjones, a=akeybl
ipc/chromium/src/chrome/common/ipc_channel_posix.cc
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -358,16 +358,26 @@ bool Channel::ChannelImpl::EnqueueHelloM
     Close();
     return false;
   }
 
   output_queue_.push(msg.release());
   return true;
 }
 
+static void
+ClearAndShrink(std::string& s, size_t capacity)
+{
+  // This swap trick is the closest thing C++ has to a guaranteed way to
+  // shrink the capacity of a string.
+  std::string tmp;
+  tmp.reserve(capacity);
+  s.swap(tmp);
+}
+
 bool Channel::ChannelImpl::Connect() {
   if (mode_ == MODE_SERVER && uses_fifo_) {
     if (server_listen_pipe_ == -1) {
       return false;
     }
     MessageLoopForIO::current()->WatchFileDescriptor(
         server_listen_pipe_,
         true,
@@ -484,17 +494,17 @@ bool Channel::ChannelImpl::ProcessIncomi
     const char *end;
     if (input_overflow_buf_.empty()) {
       overflowp = NULL;
       p = input_buf_;
       end = p + bytes_read;
     } else {
       if (input_overflow_buf_.size() >
          static_cast<size_t>(kMaximumMessageSize - bytes_read)) {
-        input_overflow_buf_.clear();
+        ClearAndShrink(input_overflow_buf_, Channel::kReadBufferSize);
         LOG(ERROR) << "IPC message is too big";
         return false;
       }
       input_overflow_buf_.append(input_buf_, bytes_read);
       overflowp = p = input_overflow_buf_.data();
       end = p + input_overflow_buf_.size();
     }
 
@@ -568,17 +578,17 @@ bool Channel::ChannelImpl::ProcessIncomi
         }
         p = message_tail;
       } else {
         // Last message is partial.
         break;
       }
     }
     if (end == p) {
-      input_overflow_buf_.clear();
+      ClearAndShrink(input_overflow_buf_, Channel::kReadBufferSize);
     } else if (!overflowp) {
       // p is from input_buf_
       input_overflow_buf_.assign(p, end - p);
     } else if (p > overflowp) {
       // p is from input_overflow_buf_
       input_overflow_buf_.erase(0, p - overflowp);
     }
     input_overflow_fds_ = std::vector<int>(&fds[fds_i], &fds[num_fds]);