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:
MessagePipeHandle()32 MessagePipeHandle() {}
MessagePipeHandle(MojoHandle value)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.
CreateMessagePipe(const MojoCreateMessagePipeOptions * options,ScopedMessagePipeHandle * message_pipe0,ScopedMessagePipeHandle * message_pipe1)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.
WriteMessageNew(MessagePipeHandle message_pipe,ScopedMessageHandle message,MojoWriteMessageFlags flags)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.
ReadMessageNew(MessagePipeHandle message_pipe,ScopedMessageHandle * message,MojoReadMessageFlags flags)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.
FuseMessagePipes(ScopedMessagePipeHandle message_pipe0,ScopedMessagePipeHandle message_pipe1)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
MessagePipe()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
MessagePipe(const MojoCreateMessagePipeOptions & options)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
~MessagePipe()152 inline MessagePipe::~MessagePipe() {
153 }
154
155 } // namespace mojo
156
157 #endif // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_
158