Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / mojo / edk / system / message_in_transit.h
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_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_
6 #define MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <vector>
12
13 #include "base/macros.h"
14 #include "base/memory/aligned_memory.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "mojo/edk/system/channel_endpoint_id.h"
17 #include "mojo/edk/system/dispatcher.h"
18 #include "mojo/edk/system/memory.h"
19 #include "mojo/edk/system/system_impl_export.h"
20
21 namespace mojo {
22 namespace system {
23
24 class Channel;
25 class TransportData;
26
27 // This class is used to represent data in transit. It is thread-unsafe.
28 //
29 // |MessageInTransit| buffers:
30 //
31 // A |MessageInTransit| can be serialized by writing the main buffer and then,
32 // if it has one, the transport data buffer. Both buffers are
33 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes
34 // in size.
35 //
36 // The main buffer consists of the header (of type |Header|, which is an
37 // internal detail of this class) followed immediately by the message data
38 // (accessed by |bytes()| and of size |num_bytes()|, and also
39 // |kMessageAlignment|-byte aligned), and then any padding needed to make the
40 // main buffer a multiple of |kMessageAlignment| bytes in size.
41 //
42 // See |TransportData| for a description of the (serialized) transport data
43 // buffer.
44 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit {
45  public:
46   typedef uint16_t Type;
47   // Messages that are forwarded to |MessagePipeEndpoint|s.
48   static const Type kTypeMessagePipeEndpoint = 0;
49   // Messages that are forwarded to |MessagePipe|s.
50   static const Type kTypeMessagePipe = 1;
51   // Messages that are consumed by the |Channel|.
52   static const Type kTypeChannel = 2;
53   // Messages that are consumed by the |RawChannel| (implementation).
54   static const Type kTypeRawChannel = 3;
55
56   typedef uint16_t Subtype;
57   // Subtypes for type |kTypeMessagePipeEndpoint|:
58   static const Subtype kSubtypeMessagePipeEndpointData = 0;
59   // Subtypes for type |kTypeMessagePipe|:
60   // Nothing currently.
61   // Subtypes for type |kTypeChannel|:
62   static const Subtype kSubtypeChannelAttachAndRunEndpoint = 0;
63   static const Subtype kSubtypeChannelRemoveMessagePipeEndpoint = 1;
64   static const Subtype kSubtypeChannelRemoveMessagePipeEndpointAck = 2;
65
66   // Subtypes for type |kTypeRawChannel|:
67   static const Subtype kSubtypeRawChannelPosixExtraPlatformHandles = 0;
68
69   // Messages (the header and data) must always be aligned to a multiple of this
70   // quantity (which must be a power of 2).
71   static const size_t kMessageAlignment = 8;
72
73   // Forward-declare |Header| so that |View| can use it:
74  private:
75   struct Header;
76
77  public:
78   // This represents a view of serialized message data in a raw buffer.
79   class MOJO_SYSTEM_IMPL_EXPORT View {
80    public:
81     // Constructs a view from the given buffer of the given size. (The size must
82     // be as provided by |MessageInTransit::GetNextMessageSize()|.) The buffer
83     // must remain alive/unmodified through the lifetime of this object.
84     // |buffer| should be |kMessageAlignment|-byte aligned.
85     View(size_t message_size, const void* buffer);
86
87     // Checks that the given |View| appears to be for a valid message, within
88     // predetermined limits (e.g., |num_bytes()| and |main_buffer_size()|, that
89     // |transport_data_buffer()|/|transport_data_buffer_size()| is for valid
90     // transport data -- see |TransportData::ValidateBuffer()|).
91     //
92     // It returns true (and leaves |error_message| alone) if this object appears
93     // to be a valid message (according to the above) and false, pointing
94     // |*error_message| to a suitable error message, if not.
95     bool IsValid(size_t serialized_platform_handle_size,
96                  const char** error_message) const;
97
98     // API parallel to that for |MessageInTransit| itself (mostly getters for
99     // header data).
100     const void* main_buffer() const { return buffer_; }
101     size_t main_buffer_size() const {
102       return RoundUpMessageAlignment(sizeof(Header) + header()->num_bytes);
103     }
104     const void* transport_data_buffer() const {
105       return (total_size() > main_buffer_size())
106                  ? static_cast<const char*>(buffer_) + main_buffer_size()
107                  : nullptr;
108     }
109     size_t transport_data_buffer_size() const {
110       return total_size() - main_buffer_size();
111     }
112     size_t total_size() const { return header()->total_size; }
113     uint32_t num_bytes() const { return header()->num_bytes; }
114     const void* bytes() const {
115       return static_cast<const char*>(buffer_) + sizeof(Header);
116     }
117     Type type() const { return header()->type; }
118     Subtype subtype() const { return header()->subtype; }
119     ChannelEndpointId source_id() const { return header()->source_id; }
120     ChannelEndpointId destination_id() const {
121       return header()->destination_id;
122     }
123
124    private:
125     const Header* header() const { return static_cast<const Header*>(buffer_); }
126
127     const void* const buffer_;
128
129     // Though this struct is trivial, disallow copy and assign, since it doesn't
130     // own its data. (If you're copying/assigning this, you're probably doing
131     // something wrong.)
132     DISALLOW_COPY_AND_ASSIGN(View);
133   };
134
135   // |bytes| is optional; if null, the message data will be zero-initialized.
136   MessageInTransit(Type type,
137                    Subtype subtype,
138                    uint32_t num_bytes,
139                    const void* bytes);
140   // |bytes| should be valid (and non-null), unless |num_bytes| is zero.
141   MessageInTransit(Type type,
142                    Subtype subtype,
143                    uint32_t num_bytes,
144                    UserPointer<const void> bytes);
145   // Constructs a |MessageInTransit| from a |View|.
146   explicit MessageInTransit(const View& message_view);
147
148   ~MessageInTransit();
149
150   // Gets the size of the next message from |buffer|, which has |buffer_size|
151   // bytes currently available, returning true and setting |*next_message_size|
152   // on success. |buffer| should be aligned on a |kMessageAlignment| boundary
153   // (and on success, |*next_message_size| will be a multiple of
154   // |kMessageAlignment|).
155   // TODO(vtl): In |RawChannelPosix|, the alignment requirements are currently
156   // satisified on a faith-based basis.
157   static bool GetNextMessageSize(const void* buffer,
158                                  size_t buffer_size,
159                                  size_t* next_message_size);
160
161   // Makes this message "own" the given set of dispatchers. The dispatchers must
162   // not be referenced from anywhere else (in particular, not from the handle
163   // table), i.e., each dispatcher must have a reference count of 1. This
164   // message must not already have dispatchers.
165   void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers);
166
167   // Sets the |TransportData| for this message. This should only be done when
168   // there are no dispatchers and no existing |TransportData|.
169   void SetTransportData(scoped_ptr<TransportData> transport_data);
170
171   // Serializes any dispatchers to the secondary buffer. This message must not
172   // already have a secondary buffer (so this must only be called once). The
173   // caller must ensure (e.g., by holding on to a reference) that |channel|
174   // stays alive through the call.
175   void SerializeAndCloseDispatchers(Channel* channel);
176
177   // Gets the main buffer and its size (in number of bytes), respectively.
178   const void* main_buffer() const { return main_buffer_.get(); }
179   size_t main_buffer_size() const { return main_buffer_size_; }
180
181   // Gets the transport data buffer (if any).
182   const TransportData* transport_data() const { return transport_data_.get(); }
183   TransportData* transport_data() { return transport_data_.get(); }
184
185   // Gets the total size of the message (see comment in |Header|, below).
186   size_t total_size() const { return header()->total_size; }
187
188   // Gets the size of the message data.
189   uint32_t num_bytes() const { return header()->num_bytes; }
190
191   // Gets the message data (of size |num_bytes()| bytes).
192   const void* bytes() const { return main_buffer_.get() + sizeof(Header); }
193   void* bytes() { return main_buffer_.get() + sizeof(Header); }
194
195   Type type() const { return header()->type; }
196   Subtype subtype() const { return header()->subtype; }
197   ChannelEndpointId source_id() const { return header()->source_id; }
198   ChannelEndpointId destination_id() const { return header()->destination_id; }
199
200   void set_source_id(ChannelEndpointId source_id) {
201     header()->source_id = source_id;
202   }
203   void set_destination_id(ChannelEndpointId destination_id) {
204     header()->destination_id = destination_id;
205   }
206
207   // Gets the dispatchers attached to this message; this may return null if
208   // there are none. Note that the caller may mutate the set of dispatchers
209   // (e.g., take ownership of all the dispatchers, leaving the vector empty).
210   DispatcherVector* dispatchers() { return dispatchers_.get(); }
211
212   // Returns true if this message has dispatchers attached.
213   bool has_dispatchers() const {
214     return dispatchers_ && !dispatchers_->empty();
215   }
216
217   // Rounds |n| up to a multiple of |kMessageAlignment|.
218   static inline size_t RoundUpMessageAlignment(size_t n) {
219     return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1);
220   }
221
222  private:
223   // To allow us to make compile-assertions about |Header| in the .cc file.
224   struct PrivateStructForCompileAsserts;
225
226   // Header for the data (main buffer). Must be a multiple of
227   // |kMessageAlignment| bytes in size. Must be POD.
228   struct Header {
229     // Total size of the message, including the header, the message data
230     // ("bytes") including padding (to make it a multiple of |kMessageAlignment|
231     // bytes), and serialized handle information. Note that this may not be the
232     // correct value if dispatchers are attached but
233     // |SerializeAndCloseDispatchers()| has not been called.
234     uint32_t total_size;
235     Type type;                         // 2 bytes.
236     Subtype subtype;                   // 2 bytes.
237     ChannelEndpointId source_id;       // 4 bytes.
238     ChannelEndpointId destination_id;  // 4 bytes.
239     // Size of actual message data.
240     uint32_t num_bytes;
241     uint32_t unused;
242   };
243
244   const Header* header() const {
245     return reinterpret_cast<const Header*>(main_buffer_.get());
246   }
247   Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); }
248
249   void ConstructorHelper(Type type, Subtype subtype, uint32_t num_bytes);
250   void UpdateTotalSize();
251
252   const size_t main_buffer_size_;
253   const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_;  // Never null.
254
255   scoped_ptr<TransportData> transport_data_;  // May be null.
256
257   // Any dispatchers that may be attached to this message. These dispatchers
258   // should be "owned" by this message, i.e., have a ref count of exactly 1. (We
259   // allow a dispatcher entry to be null, in case it couldn't be duplicated for
260   // some reason.)
261   scoped_ptr<DispatcherVector> dispatchers_;
262
263   DISALLOW_COPY_AND_ASSIGN(MessageInTransit);
264 };
265
266 }  // namespace system
267 }  // namespace mojo
268
269 #endif  // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_