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 "base/compiler_specific.h"
     18 #include "base/logging.h"
     19 #include "mojo/public/c/system/message_pipe.h"
     20 #include "mojo/public/cpp/system/handle.h"
     21 #include "mojo/public/cpp/system/message.h"
     22 
     23 namespace mojo {
     24 
     25 // A strongly-typed representation of a |MojoHandle| to one end of a message
     26 // pipe.
     27 class MessagePipeHandle : public Handle {
     28  public:
     29   MessagePipeHandle() {}
     30   explicit MessagePipeHandle(MojoHandle value) : Handle(value) {}
     31 
     32   // Copying and assignment allowed.
     33 };
     34 
     35 static_assert(sizeof(MessagePipeHandle) == sizeof(Handle),
     36               "Bad size for C++ MessagePipeHandle");
     37 
     38 typedef ScopedHandleBase<MessagePipeHandle> ScopedMessagePipeHandle;
     39 static_assert(sizeof(ScopedMessagePipeHandle) == sizeof(MessagePipeHandle),
     40               "Bad size for C++ ScopedMessagePipeHandle");
     41 
     42 // Creates a message pipe. See |MojoCreateMessagePipe()| for complete
     43 // documentation.
     44 inline MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options,
     45                                     ScopedMessagePipeHandle* message_pipe0,
     46                                     ScopedMessagePipeHandle* message_pipe1) {
     47   DCHECK(message_pipe0);
     48   DCHECK(message_pipe1);
     49   MessagePipeHandle handle0;
     50   MessagePipeHandle handle1;
     51   MojoResult rv = MojoCreateMessagePipe(
     52       options, handle0.mutable_value(), handle1.mutable_value());
     53   // Reset even on failure (reduces the chances that a "stale"/incorrect handle
     54   // will be used).
     55   message_pipe0->reset(handle0);
     56   message_pipe1->reset(handle1);
     57   return rv;
     58 }
     59 
     60 // The following "...Raw" versions fully expose the underlying API, and don't
     61 // help with ownership of handles (especially when writing messages). It is
     62 // expected that in most cases these methods will be called through generated
     63 // bindings anyway.
     64 // TODO(vtl): Write friendlier versions of these functions (using scoped
     65 // handles and/or vectors) if there is a demonstrated need for them.
     66 
     67 // Writes to a message pipe.  If handles are attached, on success the handles
     68 // will no longer be valid (the receiver will receive equivalent, but logically
     69 // different, handles). See |MojoWriteMessage()| for complete documentation.
     70 inline MojoResult WriteMessageRaw(MessagePipeHandle message_pipe,
     71                                   const void* bytes,
     72                                   uint32_t num_bytes,
     73                                   const MojoHandle* handles,
     74                                   uint32_t num_handles,
     75                                   MojoWriteMessageFlags flags) {
     76   return MojoWriteMessage(
     77       message_pipe.value(), bytes, num_bytes, handles, num_handles, flags);
     78 }
     79 
     80 // Reads from a message pipe. See |MojoReadMessage()| for complete
     81 // documentation.
     82 inline MojoResult ReadMessageRaw(MessagePipeHandle message_pipe,
     83                                  void* bytes,
     84                                  uint32_t* num_bytes,
     85                                  MojoHandle* handles,
     86                                  uint32_t* num_handles,
     87                                  MojoReadMessageFlags flags) {
     88   return MojoReadMessage(
     89       message_pipe.value(), bytes, num_bytes, handles, num_handles, flags);
     90 }
     91 
     92 // Writes to a message pipe. Takes ownership of |message| and any attached
     93 // handles.
     94 inline MojoResult WriteMessageNew(MessagePipeHandle message_pipe,
     95                                   ScopedMessageHandle message,
     96                                   MojoWriteMessageFlags flags) {
     97   return MojoWriteMessageNew(
     98       message_pipe.value(), message.release().value(), flags);
     99 }
    100 
    101 // Reads from a message pipe. See |MojoReadMessageNew()| for complete
    102 // documentation.
    103 inline MojoResult ReadMessageNew(MessagePipeHandle message_pipe,
    104                                  ScopedMessageHandle* message,
    105                                  uint32_t* num_bytes,
    106                                  MojoHandle* handles,
    107                                  uint32_t* num_handles,
    108                                  MojoReadMessageFlags flags) {
    109   MojoMessageHandle raw_message;
    110   MojoResult rv = MojoReadMessageNew(message_pipe.value(), &raw_message,
    111                                      num_bytes, handles, num_handles, flags);
    112   if (rv != MOJO_RESULT_OK)
    113     return rv;
    114 
    115   message->reset(MessageHandle(raw_message));
    116   return MOJO_RESULT_OK;
    117 }
    118 
    119 // Fuses two message pipes together at the given handles. See
    120 // |MojoFuseMessagePipes()| for complete documentation.
    121 inline MojoResult FuseMessagePipes(ScopedMessagePipeHandle message_pipe0,
    122                                    ScopedMessagePipeHandle message_pipe1) {
    123   return MojoFuseMessagePipes(message_pipe0.release().value(),
    124                               message_pipe1.release().value());
    125 }
    126 
    127 // A wrapper class that automatically creates a message pipe and owns both
    128 // handles.
    129 class MessagePipe {
    130  public:
    131   MessagePipe();
    132   explicit MessagePipe(const MojoCreateMessagePipeOptions& options);
    133   ~MessagePipe();
    134 
    135   ScopedMessagePipeHandle handle0;
    136   ScopedMessagePipeHandle handle1;
    137 };
    138 
    139 inline MessagePipe::MessagePipe() {
    140   MojoResult result = CreateMessagePipe(nullptr, &handle0, &handle1);
    141   DCHECK_EQ(MOJO_RESULT_OK, result);
    142   DCHECK(handle0.is_valid());
    143   DCHECK(handle1.is_valid());
    144 }
    145 
    146 inline MessagePipe::MessagePipe(const MojoCreateMessagePipeOptions& options) {
    147   MojoResult result = CreateMessagePipe(&options, &handle0, &handle1);
    148   DCHECK_EQ(MOJO_RESULT_OK, result);
    149   DCHECK(handle0.is_valid());
    150   DCHECK(handle1.is_valid());
    151 }
    152 
    153 inline MessagePipe::~MessagePipe() {
    154 }
    155 
    156 }  // namespace mojo
    157 
    158 #endif  // MOJO_PUBLIC_CPP_SYSTEM_MESSAGE_PIPE_H_
    159