1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // This file provides a C++ wrapping around the Mojo C API for message pipes, 6 // replacing the prefix of "Mojo" with a "mojo" namespace, and using more 7 // strongly-typed representations of |MojoHandle|s. 8 // 9 // Please see "mojo/public/c/system/message_pipe.h" for complete documentation 10 // of the API. 11 12 #ifndef MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_ 13 #define MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_ 14 15 #include <stdint.h> 16 17 #include "base/compiler_specific.h" 18 #include "base/logging.h" 19 #include "mojo/public/c/system/message_pipe.h" 20 #include "mojo/public/cpp/system/handle.h" 21 #include "mojo/public/cpp/system/message.h" 22 23 namespace mojo { 24 25 // A strongly-typed representation of a |MojoHandle| to one end of a message 26 // pipe. 27 class MessagePipeHandle : public Handle { 28 public: 29 MessagePipeHandle() {} 30 explicit MessagePipeHandle(MojoHandle value) : Handle(value) {} 31 32 // Copying and assignment allowed. 33 }; 34 35 static_assert(sizeof(MessagePipeHandle) == sizeof(Handle), 36 "Bad size for C++ MessagePipeHandle"); 37 38 typedef ScopedHandleBase<MessagePipeHandle> ScopedMessagePipeHandle; 39 static_assert(sizeof(ScopedMessagePipeHandle) == sizeof(MessagePipeHandle), 40 "Bad size for C++ ScopedMessagePipeHandle"); 41 42 // Creates a message pipe. See |MojoCreateMessagePipe()| for complete 43 // documentation. 44 inline MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options, 45 ScopedMessagePipeHandle* message_pipe0, 46 ScopedMessagePipeHandle* message_pipe1) { 47 DCHECK(message_pipe0); 48 DCHECK(message_pipe1); 49 MessagePipeHandle handle0; 50 MessagePipeHandle handle1; 51 MojoResult rv = MojoCreateMessagePipe( 52 options, handle0.mutable_value(), handle1.mutable_value()); 53 // Reset even on failure (reduces the chances that a "stale"/incorrect handle 54 // will be used). 55 message_pipe0->reset(handle0); 56 message_pipe1->reset(handle1); 57 return rv; 58 } 59 60 // The following "...Raw" versions fully expose the underlying API, and don't 61 // help with ownership of handles (especially when writing messages). It is 62 // expected that in most cases these methods will be called through generated 63 // bindings anyway. 64 // TODO(vtl): Write friendlier versions of these functions (using scoped 65 // handles and/or vectors) if there is a demonstrated need for them. 66 67 // Writes to a message pipe. If handles are attached, on success the handles 68 // will no longer be valid (the receiver will receive equivalent, but logically 69 // different, handles). See |MojoWriteMessage()| for complete documentation. 70 inline MojoResult WriteMessageRaw(MessagePipeHandle message_pipe, 71 const void* bytes, 72 uint32_t num_bytes, 73 const MojoHandle* handles, 74 uint32_t num_handles, 75 MojoWriteMessageFlags flags) { 76 return MojoWriteMessage( 77 message_pipe.value(), bytes, num_bytes, handles, num_handles, flags); 78 } 79 80 // Reads from a message pipe. See |MojoReadMessage()| for complete 81 // documentation. 82 inline MojoResult ReadMessageRaw(MessagePipeHandle message_pipe, 83 void* bytes, 84 uint32_t* num_bytes, 85 MojoHandle* handles, 86 uint32_t* num_handles, 87 MojoReadMessageFlags flags) { 88 return MojoReadMessage( 89 message_pipe.value(), bytes, num_bytes, handles, num_handles, flags); 90 } 91 92 // Writes to a message pipe. Takes ownership of |message| and any attached 93 // handles. 94 inline MojoResult WriteMessageNew(MessagePipeHandle message_pipe, 95 ScopedMessageHandle message, 96 MojoWriteMessageFlags flags) { 97 return MojoWriteMessageNew( 98 message_pipe.value(), message.release().value(), flags); 99 } 100 101 // Reads from a message pipe. See |MojoReadMessageNew()| for complete 102 // documentation. 103 inline MojoResult ReadMessageNew(MessagePipeHandle message_pipe, 104 ScopedMessageHandle* message, 105 uint32_t* num_bytes, 106 MojoHandle* handles, 107 uint32_t* num_handles, 108 MojoReadMessageFlags flags) { 109 MojoMessageHandle raw_message; 110 MojoResult rv = MojoReadMessageNew(message_pipe.value(), &raw_message, 111 num_bytes, handles, num_handles, flags); 112 if (rv != MOJO_RESULT_OK) 113 return rv; 114 115 message->reset(MessageHandle(raw_message)); 116 return MOJO_RESULT_OK; 117 } 118 119 // Fuses two message pipes together at the given handles. See 120 // |MojoFuseMessagePipes()| for complete documentation. 121 inline MojoResult FuseMessagePipes(ScopedMessagePipeHandle message_pipe0, 122 ScopedMessagePipeHandle message_pipe1) { 123 return MojoFuseMessagePipes(message_pipe0.release().value(), 124 message_pipe1.release().value()); 125 } 126 127 // A wrapper class that automatically creates a message pipe and owns both 128 // handles. 129 class MessagePipe { 130 public: 131 MessagePipe(); 132 explicit MessagePipe(const MojoCreateMessagePipeOptions& options); 133 ~MessagePipe(); 134 135 ScopedMessagePipeHandle handle0; 136 ScopedMessagePipeHandle handle1; 137 }; 138 139 inline MessagePipe::MessagePipe() { 140 MojoResult result = CreateMessagePipe(nullptr, &handle0, &handle1); 141 DCHECK_EQ(MOJO_RESULT_OK, result); 142 DCHECK(handle0.is_valid()); 143 DCHECK(handle1.is_valid()); 144 } 145 146 inline MessagePipe::MessagePipe(const MojoCreateMessagePipeOptions& options) { 147 MojoResult result = CreateMessagePipe(&options, &handle0, &handle1); 148 DCHECK_EQ(MOJO_RESULT_OK, result); 149 DCHECK(handle0.is_valid()); 150 DCHECK(handle1.is_valid()); 151 } 152 153 inline MessagePipe::~MessagePipe() { 154 } 155 156 } // namespace mojo 157 158 #endif // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_ 159