Bug 1111079 - Backport some IPC message/channel fixes. r=bent, a=lmandel
authorJed Davis <jld@mozilla.com>
Thu, 19 Mar 2015 16:07:37 -0700
changeset 250459 5bb1bb65cc28
parent 250458 aabde7671ac0
child 250460 a2295cc0de06
push id4594
push userryanvm@gmail.com
push date2015-03-20 00:14 +0000
treeherdermozilla-beta@a2295cc0de06 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, lmandel
bugs1111079
milestone37.0
Bug 1111079 - Backport some IPC message/channel fixes. r=bent, a=lmandel
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) {