Bug 1111079 - Backport some IPC message/channel fixes. r=bent a=me
authorJed Davis <jld@mozilla.com>
Thu, 19 Mar 2015 16:07:37 -0700
changeset 263418 e01fd5b164d66351c593caea975060b9597d248f
parent 263417 ec570b09456d03e9d9215931133e32efbe12bd5e
child 263419 1e23fac3251709cb7b72c736779112c046303b99
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, me
bugs1111079
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1111079 - Backport some IPC message/channel fixes. r=bent a=me
ipc/chromium/src/base/message_pump_libevent.cc
ipc/chromium/src/chrome/common/ipc_channel_posix.cc
--- a/ipc/chromium/src/base/message_pump_libevent.cc
+++ b/ipc/chromium/src/base/message_pump_libevent.cc
@@ -170,16 +170,33 @@ bool MessagePumpLibevent::WatchFileDescr
   // If we're modifying an existing event and there's an error then we need to
   // tell libevent to clean it up via event_delete() before returning.
   bool should_delete_event = true;
   mozilla::UniquePtr<event> evt(controller->ReleaseEvent());
   if (evt.get() == NULL) {
     should_delete_event = false;
     // Ownership is transferred to the controller.
     evt = mozilla::MakeUnique<event>();
+  } else {
+    // It's illegal to use this function to listen on 2 separate fds with the
+    // same |controller|.
+    if (EVENT_FD(evt.get()) != fd) {
+      NOTREACHED() << "FDs don't match" << EVENT_FD(evt.get()) << "!=" << fd;
+      return false;
+    }
+
+    // Make sure we don't pick up any funky internal libevent masks.
+    int old_interest_mask = evt.get()->ev_events &
+      (EV_READ | EV_WRITE | EV_PERSIST);
+
+    // Combine old/new event masks.
+    event_mask |= old_interest_mask;
+
+    // Must disarm the event before we can reuse it.
+    event_del(evt.get());
   }
 
   // Set current interest mask and message pump for this event.
   event_set(evt.get(), fd, event_mask, OnLibeventNotification,
             delegate);
 
   // Tell libevent which message pump this socket will belong to when we add it.
   if (event_base_set(event_base_, evt.get()) != 0) {
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -839,16 +839,18 @@ void Channel::ChannelImpl::OnFileCanRead
     waiting_connect_ = false;
     send_server_hello_msg = true;
   }
 
   if (!waiting_connect_ && fd == pipe_) {
     if (!ProcessIncomingMessages()) {
       Close();
       listener_->OnChannelError();
+      // The OnChannelError() call may delete this, so we need to exit now.
+      return;
     }
   }
 
   // If we're a server and handshaking, then we want to make sure that we
   // only send our handshake message after we've processed the client's.
   // This gives us a chance to kill the client if the incoming handshake
   // is invalid.
   if (send_server_hello_msg) {