1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// This file provides a C++ wrapping around the Mojo C API for message pipes,
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// replacing the prefix of "Mojo" with a "mojo" namespace, and using more
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// strongly-typed representations of |MojoHandle|s.
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez//
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Please see "mojo/public/c/system/message_pipe.h" for complete documentation
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// of the API.
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h>
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/compiler_specific.h"
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/logging.h"
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/c/system/message_pipe.h"
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/system/handle.h"
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/system/message.h"
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// A strongly-typed representation of a |MojoHandle| to one end of a message
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// pipe.
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MessagePipeHandle : public Handle {
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessagePipeHandle() {}
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  explicit MessagePipeHandle(MojoHandle value) : Handle(value) {}
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Copying and assignment allowed.
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezstatic_assert(sizeof(MessagePipeHandle) == sizeof(Handle),
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              "Bad size for C++ MessagePipeHandle");
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztypedef ScopedHandleBase<MessagePipeHandle> ScopedMessagePipeHandle;
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezstatic_assert(sizeof(ScopedMessagePipeHandle) == sizeof(MessagePipeHandle),
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              "Bad size for C++ ScopedMessagePipeHandle");
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Creates a message pipe. See |MojoCreateMessagePipe()| for complete
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// documentation.
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options,
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                    ScopedMessagePipeHandle* message_pipe0,
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                    ScopedMessagePipeHandle* message_pipe1) {
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK(message_pipe0);
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK(message_pipe1);
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessagePipeHandle handle0;
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessagePipeHandle handle1;
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult rv = MojoCreateMessagePipe(
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      options, handle0.mutable_value(), handle1.mutable_value());
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Reset even on failure (reduces the chances that a "stale"/incorrect handle
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // will be used).
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  message_pipe0->reset(handle0);
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  message_pipe1->reset(handle1);
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return rv;
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// The following "...Raw" versions fully expose the underlying API, and don't
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// help with ownership of handles (especially when writing messages). It is
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// expected that in most cases these methods will be called through generated
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// bindings anyway.
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// TODO(vtl): Write friendlier versions of these functions (using scoped
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// handles and/or vectors) if there is a demonstrated need for them.
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Writes to a message pipe.  If handles are attached, on success the handles
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// will no longer be valid (the receiver will receive equivalent, but logically
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// different, handles). See |MojoWriteMessage()| for complete documentation.
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MojoResult WriteMessageRaw(MessagePipeHandle message_pipe,
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  const void* bytes,
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  uint32_t num_bytes,
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  const MojoHandle* handles,
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  uint32_t num_handles,
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  MojoWriteMessageFlags flags) {
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return MojoWriteMessage(
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      message_pipe.value(), bytes, num_bytes, handles, num_handles, flags);
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Reads from a message pipe. See |MojoReadMessage()| for complete
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// documentation.
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MojoResult ReadMessageRaw(MessagePipeHandle message_pipe,
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 void* bytes,
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 uint32_t* num_bytes,
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MojoHandle* handles,
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 uint32_t* num_handles,
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MojoReadMessageFlags flags) {
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return MojoReadMessage(
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      message_pipe.value(), bytes, num_bytes, handles, num_handles, flags);
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Writes to a message pipe. Takes ownership of |message| and any attached
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// handles.
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MojoResult WriteMessageNew(MessagePipeHandle message_pipe,
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  ScopedMessageHandle message,
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                  MojoWriteMessageFlags flags) {
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return MojoWriteMessageNew(
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      message_pipe.value(), message.release().value(), flags);
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Reads from a message pipe. See |MojoReadMessageNew()| for complete
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// documentation.
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MojoResult ReadMessageNew(MessagePipeHandle message_pipe,
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 ScopedMessageHandle* message,
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 uint32_t* num_bytes,
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MojoHandle* handles,
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 uint32_t* num_handles,
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                 MojoReadMessageFlags flags) {
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoMessageHandle raw_message;
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult rv = MojoReadMessageNew(message_pipe.value(), &raw_message,
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                     num_bytes, handles, num_handles, flags);
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (rv != MOJO_RESULT_OK)
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    return rv;
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  message->reset(MessageHandle(raw_message));
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return MOJO_RESULT_OK;
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Fuses two message pipes together at the given handles. See
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// |MojoFuseMessagePipes()| for complete documentation.
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MojoResult FuseMessagePipes(ScopedMessagePipeHandle message_pipe0,
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                                   ScopedMessagePipeHandle message_pipe1) {
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  return MojoFuseMessagePipes(message_pipe0.release().value(),
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                              message_pipe1.release().value());
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// A wrapper class that automatically creates a message pipe and owns both
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// handles.
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MessagePipe {
130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessagePipe();
132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  explicit MessagePipe(const MojoCreateMessagePipeOptions& options);
133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~MessagePipe();
134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ScopedMessagePipeHandle handle0;
136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ScopedMessagePipeHandle handle1;
137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MessagePipe::MessagePipe() {
140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult result = CreateMessagePipe(nullptr, &handle0, &handle1);
141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK_EQ(MOJO_RESULT_OK, result);
142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK(handle0.is_valid());
143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK(handle1.is_valid());
144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MessagePipe::MessagePipe(const MojoCreateMessagePipeOptions& options) {
147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult result = CreateMessagePipe(&options, &handle0, &handle1);
148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK_EQ(MOJO_RESULT_OK, result);
149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK(handle0.is_valid());
150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DCHECK(handle1.is_valid());
151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline MessagePipe::~MessagePipe() {
154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif  // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_
159