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