Properly "handle" MOJO_RESULT_BUSY in a few flaces.

R=jamesr@chromium.org

Review URL: https://codereview.chromium.org/1825553002 .
diff --git a/mojo/message_pump/message_pump_mojo.cc b/mojo/message_pump/message_pump_mojo.cc
index accd345..471a0ad 100644
--- a/mojo/message_pump/message_pump_mojo.cc
+++ b/mojo/message_pump/message_pump_mojo.cc
@@ -205,7 +205,6 @@
     }
   } else {
     switch (result) {
-      case MOJO_RESULT_CANCELLED:
       case MOJO_RESULT_FAILED_PRECONDITION:
         RemoveInvalidHandle(*run_state_->wait_state, result,
                             wait_many_result.index);
@@ -213,6 +212,11 @@
       case MOJO_RESULT_DEADLINE_EXCEEDED:
         did_work = false;
         break;
+      case MOJO_RESULT_INVALID_ARGUMENT:
+      case MOJO_RESULT_CANCELLED:
+      case MOJO_RESULT_BUSY:
+        // These results indicate a bug in "our" code (e.g., race conditions).
+        // Fall through.
       default:
         base::debug::Alias(&result);
         // Unexpected result is likely fatal, crash so we can determine cause.
diff --git a/mojo/public/cpp/system/tests/core_unittest.cc b/mojo/public/cpp/system/tests/core_unittest.cc
index 686f6c6..6df03bf 100644
--- a/mojo/public/cpp/system/tests/core_unittest.cc
+++ b/mojo/public/cpp/system/tests/core_unittest.cc
@@ -493,6 +493,50 @@
   EXPECT_TRUE(buffer1.is_valid());
 }
 
+TEST(CoreCppTest, WaitManyResult) {
+  {
+    WaitManyResult wmr(MOJO_RESULT_OK);
+    EXPECT_FALSE(wmr.IsIndexValid());
+    EXPECT_TRUE(wmr.AreSignalsStatesValid());
+    EXPECT_EQ(MOJO_RESULT_OK, wmr.result);
+  }
+
+  {
+    WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION);
+    EXPECT_FALSE(wmr.IsIndexValid());
+    EXPECT_TRUE(wmr.AreSignalsStatesValid());
+    EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, wmr.result);
+  }
+
+  {
+    WaitManyResult wmr(MOJO_RESULT_INVALID_ARGUMENT);
+    EXPECT_FALSE(wmr.IsIndexValid());
+    EXPECT_FALSE(wmr.AreSignalsStatesValid());
+    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, wmr.result);
+  }
+
+  // These should be like "invalid argument".
+  EXPECT_FALSE(
+      WaitManyResult(MOJO_RESULT_RESOURCE_EXHAUSTED).AreSignalsStatesValid());
+  EXPECT_FALSE(WaitManyResult(MOJO_RESULT_BUSY).AreSignalsStatesValid());
+
+  {
+    WaitManyResult wmr(MOJO_RESULT_OK, 5u);
+    EXPECT_TRUE(wmr.IsIndexValid());
+    EXPECT_TRUE(wmr.AreSignalsStatesValid());
+    EXPECT_EQ(MOJO_RESULT_OK, wmr.result);
+    EXPECT_EQ(5u, wmr.index);
+  }
+
+  {
+    WaitManyResult wmr(MOJO_RESULT_FAILED_PRECONDITION, 5u);
+    EXPECT_TRUE(wmr.IsIndexValid());
+    EXPECT_TRUE(wmr.AreSignalsStatesValid());
+    EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, wmr.result);
+    EXPECT_EQ(5u, wmr.index);
+  }
+}
+
 // TODO(vtl): Write data pipe tests.
 
 }  // namespace
diff --git a/mojo/public/cpp/system/wait.h b/mojo/public/cpp/system/wait.h
index 5403cf6..a3871d5 100644
--- a/mojo/public/cpp/system/wait.h
+++ b/mojo/public/cpp/system/wait.h
@@ -44,7 +44,8 @@
   // helper function to check if |signals_states| holds valid data.
   bool AreSignalsStatesValid() const {
     return result != MOJO_RESULT_INVALID_ARGUMENT &&
-           result != MOJO_RESULT_RESOURCE_EXHAUSTED;
+           result != MOJO_RESULT_RESOURCE_EXHAUSTED &&
+           result != MOJO_RESULT_BUSY;
   }
 
   MojoResult result;
diff --git a/mojo/public/cpp/utility/lib/run_loop.cc b/mojo/public/cpp/utility/lib/run_loop.cc
index f554720..f68ad79 100644
--- a/mojo/public/cpp/utility/lib/run_loop.cc
+++ b/mojo/public/cpp/utility/lib/run_loop.cc
@@ -169,6 +169,11 @@
       handler->OnHandleReady(handle);
       return true;
     case MOJO_RESULT_INVALID_ARGUMENT:
+    case MOJO_RESULT_CANCELLED:
+    case MOJO_RESULT_BUSY:
+      // These results indicate a bug in "our" code (e.g., race conditions).
+      assert(false);
+      // Fall through.
     case MOJO_RESULT_FAILED_PRECONDITION:
       // Remove the handle first, this way if OnHandleError() tries to remove
       // the handle our iterator isn't invalidated.