Home | History | Annotate | Download | only in system
      1 // Copyright 2013 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 #ifndef MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_
      6 #define MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_
      7 
      8 #include <stdint.h>
      9 #include <stdlib.h>  // For |free()|.
     10 
     11 #include "base/basictypes.h"
     12 #include "mojo/system/system_impl_export.h"
     13 
     14 namespace mojo {
     15 namespace system {
     16 
     17 // This class is used to represent data in transit. It is thread-unsafe.
     18 // Note: This class is POD.
     19 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit {
     20  public:
     21   typedef uint16_t Type;
     22   // Messages that are forwarded to |MessagePipeEndpoint|s.
     23   static const Type kTypeMessagePipeEndpoint = 0;
     24   // Messages that are forwarded to |MessagePipe|s.
     25   static const Type kTypeMessagePipe = 1;
     26   // Messages that are consumed by the channel.
     27   static const Type TYPE_CHANNEL = 2;
     28 
     29   typedef uint16_t Subtype;
     30   // Subtypes for type |kTypeMessagePipeEndpoint|:
     31   static const Subtype kSubtypeMessagePipeEndpointData = 0;
     32   // Subtypes for type |kTypeMessagePipe|:
     33   static const Subtype kSubtypeMessagePipePeerClosed = 0;
     34 
     35   typedef uint32_t EndpointId;
     36   // Never a valid endpoint ID.
     37   static const EndpointId kInvalidEndpointId = 0;
     38 
     39   // Messages (the header and data) must always be aligned to a multiple of this
     40   // quantity (which must be a power of 2).
     41   static const size_t kMessageAlignment = 8;
     42 
     43   // Creates a |MessageInTransit| of the given |type| and |subtype|, with the
     44   // data given by |bytes|/|num_bytes|.
     45   static MessageInTransit* Create(Type type, Subtype subtype,
     46                                   const void* bytes, uint32_t num_bytes);
     47 
     48   // Destroys a |MessageInTransit| created using |Create()|.
     49   inline void Destroy() {
     50     // No need to call the destructor, since we're POD.
     51     free(this);
     52   }
     53 
     54   // Gets the size of the data (in number of bytes).
     55   uint32_t data_size() const {
     56     return size_;
     57   }
     58 
     59   // Gets the data (of size |size()| bytes).
     60   const void* data() const {
     61     return reinterpret_cast<const char*>(this) + sizeof(*this);
     62   }
     63 
     64   size_t size_with_header_and_padding() const {
     65     return RoundUpMessageAlignment(sizeof(*this) + size_);
     66   }
     67 
     68   Type type() const { return type_; }
     69   Subtype subtype() const { return subtype_; }
     70   EndpointId source_id() const { return source_id_; }
     71   EndpointId destination_id() const { return destination_id_; }
     72 
     73   void set_source_id(EndpointId source_id) { source_id_ = source_id; }
     74   void set_destination_id(EndpointId destination_id) {
     75     destination_id_ = destination_id;
     76   }
     77 
     78   // TODO(vtl): Add whatever's necessary to transport handles.
     79 
     80   // Rounds |n| up to a multiple of |kMessageAlignment|.
     81   static inline size_t RoundUpMessageAlignment(size_t n) {
     82     return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1);
     83   }
     84 
     85  private:
     86   explicit MessageInTransit(uint32_t size, Type type, Subtype subtype)
     87       : size_(size),
     88         type_(type),
     89         subtype_(subtype),
     90         source_id_(kInvalidEndpointId),
     91         destination_id_(kInvalidEndpointId) {}
     92 
     93   // "Header" for the data.
     94   uint32_t size_;
     95   Type type_;
     96   Subtype subtype_;
     97   EndpointId source_id_;
     98   EndpointId destination_id_;
     99 
    100   // Intentionally unimplemented (and private): Use |Destroy()| instead (which
    101   // simply frees the memory).
    102   ~MessageInTransit();
    103 
    104   DISALLOW_COPY_AND_ASSIGN(MessageInTransit);
    105 };
    106 
    107 // The size of |MessageInTransit| must be appropriate to maintain alignment of
    108 // the following data.
    109 COMPILE_ASSERT(sizeof(MessageInTransit) == 16, MessageInTransit_has_wrong_size);
    110 
    111 }  // namespace system
    112 }  // namespace mojo
    113 
    114 #endif  // MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_
    115