Mac: Ensure that Mach messages always get a reply

It may be that not getting replies from Mach messages was causing the
renderer to hang (appearing as a persistent blank white screen).

In particular, we send IOSurface Register and Acquire functions with the
flags MACH_SEND_MSG | MACH_RCV_MSG, but, if the browser doesn't
understand the request, it never sends the message back to the renderer,
so the receive part hangs forever.

Add a flag containing the result of the browser's operation, and, if
the renderer would not have gotten a message back (and would have hung),
just crash the renderer.

BUG=532149

Review URL: https://codereview.chromium.org/1351753002

Cr-Commit-Position: refs/heads/master@{#349743}
diff --git a/content/browser/browser_io_surface_manager_mac.cc b/content/browser/browser_io_surface_manager_mac.cc
index de39c37..898fa4b2 100644
--- a/content/browser/browser_io_surface_manager_mac.cc
+++ b/content/browser/browser_io_surface_manager_mac.cc
@@ -206,10 +206,8 @@
 
   switch (request.msg.header.msgh_id) {
     case IOSurfaceManagerHostMsg_RegisterIOSurface::ID:
-      if (!HandleRegisterIOSurfaceRequest(request.msg.register_io_surface,
-                                          &reply.register_io_surface)) {
-        return;
-      }
+      HandleRegisterIOSurfaceRequest(request.msg.register_io_surface,
+                                     &reply.register_io_surface);
       break;
     case IOSurfaceManagerHostMsg_UnregisterIOSurface::ID:
       HandleUnregisterIOSurfaceRequest(request.msg.unregister_io_surface);
@@ -219,10 +217,8 @@
       // process.
       return;
     case IOSurfaceManagerHostMsg_AcquireIOSurface::ID:
-      if (!HandleAcquireIOSurfaceRequest(request.msg.acquire_io_surface,
-                                         &reply.acquire_io_surface)) {
-        return;
-      }
+      HandleAcquireIOSurfaceRequest(request.msg.acquire_io_surface,
+                                    &reply.acquire_io_surface);
       break;
     default:
       LOG(ERROR) << "Unknown message received!";
@@ -237,29 +233,30 @@
   }
 }
 
-bool BrowserIOSurfaceManager::HandleRegisterIOSurfaceRequest(
+void BrowserIOSurfaceManager::HandleRegisterIOSurfaceRequest(
     const IOSurfaceManagerHostMsg_RegisterIOSurface& request,
     IOSurfaceManagerMsg_RegisterIOSurfaceReply* reply) {
   base::AutoLock lock(lock_);
 
+  reply->header.msgh_bits = MACH_MSGH_BITS_REMOTE(request.header.msgh_bits);
+  reply->header.msgh_remote_port = request.header.msgh_remote_port;
+  reply->header.msgh_size = sizeof(*reply);
+  reply->body.msgh_descriptor_count = 0;
+  reply->result = false;
+
   IOSurfaceManagerToken token;
   static_assert(sizeof(request.token_name) == sizeof(token.name),
                 "Mach message token size doesn't match expectation.");
   token.SetName(request.token_name);
   if (token.IsZero() || token != gpu_process_token_) {
     LOG(ERROR) << "Illegal message from non-GPU process!";
-    return false;
+    return;
   }
 
   IOSurfaceMapKey key(IOSurfaceId(request.io_surface_id), request.client_id);
   io_surfaces_.add(key, make_scoped_ptr(new base::mac::ScopedMachSendRight(
                             request.io_surface_port.name)));
-
-  reply->header.msgh_bits = MACH_MSGH_BITS_REMOTE(request.header.msgh_bits);
-  reply->header.msgh_remote_port = request.header.msgh_remote_port;
-  reply->header.msgh_size = sizeof(*reply);
   reply->result = true;
-  return true;
 }
 
 bool BrowserIOSurfaceManager::HandleUnregisterIOSurfaceRequest(
@@ -280,11 +277,21 @@
   return true;
 }
 
-bool BrowserIOSurfaceManager::HandleAcquireIOSurfaceRequest(
+void BrowserIOSurfaceManager::HandleAcquireIOSurfaceRequest(
     const IOSurfaceManagerHostMsg_AcquireIOSurface& request,
     IOSurfaceManagerMsg_AcquireIOSurfaceReply* reply) {
   base::AutoLock lock(lock_);
 
+  reply->header.msgh_bits =
+      MACH_MSGH_BITS_REMOTE(request.header.msgh_bits) | MACH_MSGH_BITS_COMPLEX;
+  reply->header.msgh_remote_port = request.header.msgh_remote_port;
+  reply->header.msgh_size = sizeof(*reply);
+  reply->body.msgh_descriptor_count = 0;
+  reply->result = false;
+  reply->io_surface_port.name = MACH_PORT_NULL;
+  reply->io_surface_port.disposition = 0;
+  reply->io_surface_port.type = 0;
+
   IOSurfaceManagerToken token;
   static_assert(sizeof(request.token_name) == sizeof(token.name),
                 "Mach message token size doesn't match expectation.");
@@ -292,27 +299,22 @@
   auto child_process_id_it = child_process_ids_.find(token);
   if (child_process_id_it == child_process_ids_.end()) {
     LOG(ERROR) << "Illegal message from non-child process!";
-    return false;
+    return;
   }
 
-  reply->header.msgh_bits =
-      MACH_MSGH_BITS_REMOTE(request.header.msgh_bits) | MACH_MSGH_BITS_COMPLEX;
-  reply->header.msgh_remote_port = request.header.msgh_remote_port;
-  reply->header.msgh_size = sizeof(*reply);
-
+  reply->result = true;
   IOSurfaceMapKey key(IOSurfaceId(request.io_surface_id),
                       child_process_id_it->second);
   auto it = io_surfaces_.find(key);
   if (it == io_surfaces_.end()) {
     LOG(ERROR) << "Invalid Id for IOSurface " << request.io_surface_id;
-    return true;
+    return;
   }
 
   reply->body.msgh_descriptor_count = 1;
   reply->io_surface_port.name = it->second->get();
   reply->io_surface_port.disposition = MACH_MSG_TYPE_COPY_SEND;
   reply->io_surface_port.type = MACH_MSG_PORT_DESCRIPTOR;
-  return true;
 }
 
 }  // namespace content