• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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