MojoReleaseMessageContext -> MojoGetMessageContext

Allows system API consumers to extract a message's context without
forcing the context to be released. Adds
MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE as a flag to capture the behavior
of the replaced MojoReleaseMessageContext.

BUG=725321

Change-Id: I44c4bc5c6ddc6820765110b43c3e3efa78bd2ddc
Reviewed-on: https://chromium-review.googlesource.com/557992
Reviewed-by: Jay Civelli <jcivelli@chromium.org>
Commit-Queue: Ken Rockot <rockot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#483838}

CrOS-Libchrome-Original-Commit: 65a6f7ed1619c1499ff114642de7266857271125
diff --git a/mojo/edk/embedder/entrypoints.cc b/mojo/edk/embedder/entrypoints.cc
index 43c4c22..9412b79 100644
--- a/mojo/edk/embedder/entrypoints.cc
+++ b/mojo/edk/embedder/entrypoints.cc
@@ -84,9 +84,10 @@
                                               handles, num_handles, flags);
 }
 
-MojoResult MojoReleaseMessageContextImpl(MojoMessageHandle message,
-                                         uintptr_t* context) {
-  return g_core->ReleaseMessageContext(message, context);
+MojoResult MojoGetMessageContextImpl(MojoMessageHandle message,
+                                     uintptr_t* context,
+                                     MojoGetMessageContextFlags flags) {
+  return g_core->GetMessageContext(message, context, flags);
 }
 
 MojoResult MojoCreateMessagePipeImpl(
@@ -262,7 +263,7 @@
                                     MojoDestroyMessageImpl,
                                     MojoSerializeMessageImpl,
                                     MojoGetSerializedMessageContentsImpl,
-                                    MojoReleaseMessageContextImpl,
+                                    MojoGetMessageContextImpl,
                                     MojoWrapPlatformHandleImpl,
                                     MojoUnwrapPlatformHandleImpl,
                                     MojoWrapPlatformSharedBufferHandleImpl,
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index c47e4aa..168bbf4 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -546,8 +546,9 @@
       UserMessageImpl::ExtractBadHandlePolicy::kAbort, handles);
 }
 
-MojoResult Core::ReleaseMessageContext(MojoMessageHandle message_handle,
-                                       uintptr_t* context) {
+MojoResult Core::GetMessageContext(MojoMessageHandle message_handle,
+                                   uintptr_t* context,
+                                   MojoGetMessageContextFlags flags) {
   if (!message_handle)
     return MOJO_RESULT_INVALID_ARGUMENT;
 
@@ -556,7 +557,10 @@
   if (!message->HasContext())
     return MOJO_RESULT_NOT_FOUND;
 
-  *context = message->ReleaseContext();
+  if (flags & MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE)
+    *context = message->ReleaseContext();
+  else
+    *context = message->context();
   return MOJO_RESULT_OK;
 }
 
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h
index 43b2253..ba98af5 100644
--- a/mojo/edk/system/core.h
+++ b/mojo/edk/system/core.h
@@ -203,8 +203,9 @@
       MojoHandle* handles,
       uint32_t* num_handles,
       MojoGetSerializedMessageContentsFlags flags);
-  MojoResult ReleaseMessageContext(MojoMessageHandle message_handle,
-                                   uintptr_t* context);
+  MojoResult GetMessageContext(MojoMessageHandle message_handle,
+                               uintptr_t* context,
+                               MojoGetMessageContextFlags flags);
   MojoResult GetProperty(MojoPropertyType type, void* value);
 
   // These methods correspond to the API functions defined in
diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc
index 7e03e85..fd9731e 100644
--- a/mojo/edk/system/core_unittest.cc
+++ b/mojo/edk/system/core_unittest.cc
@@ -209,7 +209,9 @@
   ASSERT_EQ(MOJO_RESULT_OK,
             core()->ReadMessage(h[0], &message, MOJO_READ_MESSAGE_FLAG_NONE));
   uintptr_t context;
-  ASSERT_EQ(MOJO_RESULT_OK, core()->ReleaseMessageContext(message, &context));
+  ASSERT_EQ(MOJO_RESULT_OK,
+            core()->GetMessageContext(message, &context,
+                                      MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE));
   ASSERT_EQ(kTestMessageContext, context);
   ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
 
@@ -290,7 +292,8 @@
                                                 MOJO_READ_MESSAGE_FLAG_NONE));
   uintptr_t context;
   ASSERT_EQ(MOJO_RESULT_OK,
-            core()->ReleaseMessageContext(message_handle, &context));
+            core()->GetMessageContext(message_handle, &context,
+                                      MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE));
   ASSERT_EQ(kTestMessageContext, context);
   ASSERT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
 
diff --git a/mojo/edk/system/message_unittest.cc b/mojo/edk/system/message_unittest.cc
index 07f402e..c02c1ff 100644
--- a/mojo/edk/system/message_unittest.cc
+++ b/mojo/edk/system/message_unittest.cc
@@ -45,7 +45,8 @@
     MojoMessageHandle handle = MOJO_HANDLE_INVALID;
     std::swap(handle, *message_handle);
     uintptr_t context;
-    MojoResult rv = MojoReleaseMessageContext(handle, &context);
+    MojoResult rv = MojoGetMessageContext(
+        handle, &context, MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE);
     DCHECK_EQ(MOJO_RESULT_OK, rv);
     MojoDestroyMessage(handle);
     return base::WrapUnique(reinterpret_cast<T*>(context));
@@ -385,7 +386,8 @@
             MojoReadMessage(b, &message_handle, MOJO_READ_MESSAGE_FLAG_NONE));
   uintptr_t context;
   EXPECT_EQ(MOJO_RESULT_NOT_FOUND,
-            MojoReleaseMessageContext(message_handle, &context));
+            MojoGetMessageContext(message_handle, &context,
+                                  MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE));
   MojoClose(a);
   MojoClose(b);
 }
diff --git a/mojo/public/c/system/message_pipe.h b/mojo/public/c/system/message_pipe.h
index 07967bf..d83155a 100644
--- a/mojo/public/c/system/message_pipe.h
+++ b/mojo/public/c/system/message_pipe.h
@@ -76,8 +76,24 @@
 #define MOJO_READ_MESSAGE_FLAG_NONE ((MojoReadMessageFlags)0)
 #endif
 
+// |MojoGetMessageContextFlags|: Used to specify different options for
+// |MojoGetMessageContext|.
+//   |MOJO_GET_MESSAGE_CONTEXT_FLAG_NONE| - No flags; default mode.
+//   |MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE| - Causes the message object to
+//       release its reference to its own context before returning.
+
+typedef uint32_t MojoGetMessageContextFlags;
+
+#ifdef __cplusplus
+const MojoGetMessageContextFlags MOJO_GET_MESSAGE_CONTEXT_FLAG_NONE = 0;
+const MojoGetMessageContextFlags MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE = 1;
+#else
+#define MOJO_GET_MESSAGE_CONTEXT_FLAG_NONE ((MojoGetMessageContextFlags)0)
+#define MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE ((MojoGetMessageContextFlags)1)
+#endif
+
 // |MojoGetSerializedMessageContentsFlags|: Used to specify different options
-// |MojoGetSerializedMessageContents()|.
+// for |MojoGetSerializedMessageContents()|.
 //   |MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE| - No flags; default mode.
 
 typedef uint32_t MojoGetSerializedMessageContentsFlags;
@@ -327,7 +343,7 @@
 //       not a valid message handle.
 //   |MOJO_RESULT_FAILED_PRECONDITION| if |message| is not a serialized message.
 //       The caller may either use |MojoSerializeMessage()| and try again, or
-//       use |MojoReleaseMessageContext()| to extract the message's unserialized
+//       use |MojoGetMessageContext()| to extract the message's unserialized
 //       context.
 //   |MOJO_RESULT_NOT_FOUND| if the message's serialized contents have already
 //       been extracted (or have failed to be extracted) by a previous call to
@@ -349,9 +365,12 @@
                                  uint32_t* num_handles,
                                  MojoGetSerializedMessageContentsFlags flags);
 
-// Detaches the user-provided context from a message and returns it to the
+// Extracts the user-provided context from a message and returns it to the
 // caller. This can only succeed if the message is not in a serialized form.
 //
+// |flags|: Flags to alter the behavior of this call. See
+//     |MojoGetMessageContextFlags| for details.
+//
 // Returns:
 //   |MOJO_RESULT_OK| if |message| was a valid message object which has not yet
 //       been serialized. Upon return, |*context| contains the context value
@@ -362,7 +381,9 @@
 //       and |MojoGetSerializedMessageContents()| should be called instead.
 //   |MOJO_RESULT_INVALID_ARGUMENT| if |message| is not a valid message object.
 MOJO_SYSTEM_EXPORT MojoResult
-MojoReleaseMessageContext(MojoMessageHandle message, uintptr_t* context);
+MojoGetMessageContext(MojoMessageHandle message,
+                      uintptr_t* context,
+                      MojoGetMessageContextFlags flags);
 
 // Notifies the system that a bad message was received on a message pipe,
 // according to whatever criteria the caller chooses. This ultimately tries to
diff --git a/mojo/public/c/system/tests/core_unittest.cc b/mojo/public/c/system/tests/core_unittest.cc
index 780ea63..7e02a1a 100644
--- a/mojo/public/c/system/tests/core_unittest.cc
+++ b/mojo/public/c/system/tests/core_unittest.cc
@@ -119,7 +119,9 @@
   EXPECT_EQ(MOJO_RESULT_OK,
             MojoReadMessage(h0, &message, MOJO_READ_MESSAGE_FLAG_NONE));
   uintptr_t context;
-  EXPECT_EQ(MOJO_RESULT_OK, MojoReleaseMessageContext(message, &context));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            MojoGetMessageContext(message, &context,
+                                  MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE));
   EXPECT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message));
   EXPECT_EQ(kTestMessageContext, context);
 
diff --git a/mojo/public/c/system/tests/core_unittest_pure_c.c b/mojo/public/c/system/tests/core_unittest_pure_c.c
index c5b4c5d..fc6d6a3 100644
--- a/mojo/public/c/system/tests/core_unittest_pure_c.c
+++ b/mojo/public/c/system/tests/core_unittest_pure_c.c
@@ -63,7 +63,9 @@
   EXPECT_EQ(MOJO_RESULT_OK, MojoReadMessage(handle1, &message,
                                              MOJO_READ_MESSAGE_FLAG_NONE));
   uintptr_t context;
-  EXPECT_EQ(MOJO_RESULT_OK, MojoReleaseMessageContext(message, &context));
+  EXPECT_EQ(MOJO_RESULT_OK,
+            MojoGetMessageContext(message, &context,
+                                  MOJO_GET_MESSAGE_CONTEXT_FLAG_RELEASE));
   EXPECT_EQ(42, context);
 
   EXPECT_EQ(MOJO_RESULT_OK, MojoClose(handle0));
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc
index 43a5d28..2ce9edb 100644
--- a/mojo/public/c/system/thunks.cc
+++ b/mojo/public/c/system/thunks.cc
@@ -202,10 +202,11 @@
                                                handles, num_handles, flags);
 }
 
-MojoResult MojoReleaseMessageContext(MojoMessageHandle message,
-                                     uintptr_t* context) {
-  assert(g_thunks.ReleaseMessageContext);
-  return g_thunks.ReleaseMessageContext(message, context);
+MojoResult MojoGetMessageContext(MojoMessageHandle message,
+                                 uintptr_t* context,
+                                 MojoGetMessageContextFlags flags) {
+  assert(g_thunks.GetMessageContext);
+  return g_thunks.GetMessageContext(message, context, flags);
 }
 
 MojoResult MojoWrapPlatformHandle(
diff --git a/mojo/public/c/system/thunks.h b/mojo/public/c/system/thunks.h
index e329724..c6d8abe 100644
--- a/mojo/public/c/system/thunks.h
+++ b/mojo/public/c/system/thunks.h
@@ -98,8 +98,9 @@
       MojoHandle* handles,
       uint32_t* num_handles,
       MojoGetSerializedMessageContentsFlags flags);
-  MojoResult (*ReleaseMessageContext)(MojoMessageHandle message,
-                                      uintptr_t* context);
+  MojoResult (*GetMessageContext)(MojoMessageHandle message,
+                                  uintptr_t* context,
+                                  MojoGetMessageContextFlags flags);
   MojoResult (*WrapPlatformHandle)(
       const struct MojoPlatformHandle* platform_handle,
       MojoHandle* mojo_handle);