Home | History | Annotate | Download | only in system
      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