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 <vector> 18 19 #include "base/compiler_specific.h" 20 #include "base/logging.h" 21 #include "mojo/public/c/system/message_pipe.h" 22 #include "mojo/public/cpp/system/handle.h" 23 #include "mojo/public/cpp/system/message.h" 24 #include "mojo/public/cpp/system/system_export.h" 25 26 namespace mojo { 27 28 // A strongly-typed representation of a |MojoHandle| to one end of a message 29 // pipe. 30 class MessagePipeHandle : public Handle { 31 public: 32 MessagePipeHandle() {} 33 explicit MessagePipeHandle(MojoHandle value) : Handle(value) {} 34 35 // Copying and assignment allowed. 36 }; 37 38 static_assert(sizeof(MessagePipeHandle) == sizeof(Handle), 39 "Bad size for C++ MessagePipeHandle"); 40 41 typedef ScopedHandleBase<MessagePipeHandle> ScopedMessagePipeHandle; 42 static_assert(sizeof(ScopedMessagePipeHandle) == sizeof(MessagePipeHandle), 43 "Bad size for C++ ScopedMessagePipeHandle"); 44 45 // Creates a message pipe. See |MojoCreateMessagePipe()| for complete 46 // documentation. 47 inline MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options, 48 ScopedMessagePipeHandle* message_pipe0, 49 ScopedMessagePipeHandle* message_pipe1) { 50 DCHECK(message_pipe0); 51 DCHECK(message_pipe1); 52 MessagePipeHandle handle0; 53 MessagePipeHandle handle1; 54 MojoResult rv = MojoCreateMessagePipe( 55 options, handle0.mutable_value(), handle1.mutable_value()); 56 // Reset even on failure (reduces the chances that a "stale"/incorrect handle 57 // will be used). 58 message_pipe0->reset(handle0); 59 message_pipe1->reset(handle1); 60 return rv; 61 } 62 63 // A helper for writing a serialized message to a message pipe. Use this for 64 // convenience in lieu of the lower-level MojoWriteMessage API, but beware that 65 // it does incur an extra copy of the message payload. 66 // 67 // See documentation for MojoWriteMessage for return code details. 68 MOJO_CPP_SYSTEM_EXPORT MojoResult 69 WriteMessageRaw(MessagePipeHandle message_pipe, 70 const void* bytes, 71 size_t num_bytes, 72 const MojoHandle* handles, 73 size_t num_handles, 74 MojoWriteMessageFlags flags); 75 76 // A helper for reading serialized messages from a pipe. Use this for 77 // convenience in lieu of the lower-level MojoReadMessage API, but beware that 78 // it does incur an extra copy of the message payload. 79 // 80 // See documentation for MojoReadMessage for return code details. In addition to 81 // those return codes, this may return |MOJO_RESULT_ABORTED| if the message was 82 // unable to be serialized into the provided containers. 83 MOJO_CPP_SYSTEM_EXPORT MojoResult 84 ReadMessageRaw(MessagePipeHandle message_pipe, 85 std::vector<uint8_t>* payload, 86 std::vector<ScopedHandle>* handles, 87 MojoReadMessageFlags flags); 88 89 // Writes to a message pipe. Takes ownership of |message| and any attached 90 // handles. 91 inline MojoResult WriteMessageNew(MessagePipeHandle message_pipe, 92 ScopedMessageHandle message, 93 MojoWriteMessageFlags flags) { 94 MojoWriteMessageOptions options; 95 options.struct_size = sizeof(options); 96 options.flags = flags; 97 return MojoWriteMessage(message_pipe.value(), message.release().value(), 98 &options); 99 } 100 101 // Reads from a message pipe. See |MojoReadMessage()| for complete 102 // documentation. 103 inline MojoResult ReadMessageNew(MessagePipeHandle message_pipe, 104 ScopedMessageHandle* message, 105 MojoReadMessageFlags flags) { 106 MojoReadMessageOptions options; 107 options.struct_size = sizeof(options); 108 options.flags = flags; 109 MojoMessageHandle raw_message; 110 MojoResult rv = MojoReadMessage(message_pipe.value(), &options, &raw_message); 111 if (rv != MOJO_RESULT_OK) 112 return rv; 113 114 message->reset(MessageHandle(raw_message)); 115 return MOJO_RESULT_OK; 116 } 117 118 // Fuses two message pipes together at the given handles. See 119 // |MojoFuseMessagePipes()| for complete documentation. 120 inline MojoResult FuseMessagePipes(ScopedMessagePipeHandle message_pipe0, 121 ScopedMessagePipeHandle message_pipe1) { 122 return MojoFuseMessagePipes(message_pipe0.release().value(), 123 message_pipe1.release().value(), nullptr); 124 } 125 126 // A wrapper class that automatically creates a message pipe and owns both 127 // handles. 128 class MessagePipe { 129 public: 130 MessagePipe(); 131 explicit MessagePipe(const MojoCreateMessagePipeOptions& options); 132 ~MessagePipe(); 133 134 ScopedMessagePipeHandle handle0; 135 ScopedMessagePipeHandle handle1; 136 }; 137 138 inline MessagePipe::MessagePipe() { 139 MojoResult result = CreateMessagePipe(nullptr, &handle0, &handle1); 140 DCHECK_EQ(MOJO_RESULT_OK, result); 141 DCHECK(handle0.is_valid()); 142 DCHECK(handle1.is_valid()); 143 } 144 145 inline MessagePipe::MessagePipe(const MojoCreateMessagePipeOptions& options) { 146 MojoResult result = CreateMessagePipe(&options, &handle0, &handle1); 147 DCHECK_EQ(MOJO_RESULT_OK, result); 148 DCHECK(handle0.is_valid()); 149 DCHECK(handle1.is_valid()); 150 } 151 152 inline MessagePipe::~MessagePipe() { 153 } 154 155 } // namespace mojo 156 157 #endif // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_ 158