| Index: mojo/system/transport_data.h
|
| diff --git a/mojo/system/transport_data.h b/mojo/system/transport_data.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d4d9528fc2915761a78af741a21ec03aa5198c56
|
| --- /dev/null
|
| +++ b/mojo/system/transport_data.h
|
| @@ -0,0 +1,163 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef MOJO_SYSTEM_TRANSPORT_DATA_H_
|
| +#define MOJO_SYSTEM_TRANSPORT_DATA_H_
|
| +
|
| +#include <stdint.h>
|
| +
|
| +#include <vector>
|
| +
|
| +#include "base/macros.h"
|
| +#include "base/memory/aligned_memory.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "mojo/embedder/platform_handle.h"
|
| +#include "mojo/system/dispatcher.h"
|
| +#include "mojo/system/system_impl_export.h"
|
| +
|
| +namespace mojo {
|
| +namespace system {
|
| +
|
| +// This class is used by |MessageInTransit| to represent handles (|Dispatcher|s)
|
| +// in various stages of serialization.
|
| +//
|
| +// The stages are:
|
| +// - Before reaching |TransportData|: Turn |DispatcherTransport|s into
|
| +// |Dispatcher|s that are "owned" by (and attached to) a |MessageInTransit|.
|
| +// This invalidates the handles in the space of the sending application
|
| +// (and, e.g., if another thread is waiting on such a handle, it'll be
|
| +// notified of this invalidation).
|
| +// - Serialize these dispatchers into the |TransportData|: First, for each
|
| +// attached dispatcher, there's an entry in the |TransportData|'s "handle
|
| +// table", which points to a segment of (dispatcher-type-dependent) data.
|
| +// - During the serialization of the dispatchers, |PlatformHandle|s may be
|
| +// detached from the dispatchers and attached to the |TransportData|.
|
| +// - Before sending the |MessageInTransit|, including its main buffer and the
|
| +// |TransportData|'s buffer, the |Channel| sends any |PlatformHandle|s (in a
|
| +// platform-, and possibly sandobx-situation-, specific way) first. In doing
|
| +// so, it appends a "platform handle table" to the |TransportData|
|
| +// containing information about how to deserialize these |PlatformHandle|s.
|
| +// - Finally, at this point, to send the |MessageInTransit|, there only
|
| +// remains "inert" data: the |MessageInTransit|'s main buffer and data from
|
| +// the |TransportData|, consisting of the "handle table" (one entry for each
|
| +// attached dispatcher), dispatcher-type-specific data (one segment for each
|
| +// entry in the "handle table"), and the "platform handle table" (one entry
|
| +// for each attached |PlatformHandle|).
|
| +//
|
| +// To receive a message (|MessageInTransit|), the "reverse" happens:
|
| +// - On POSIX, receive and buffer |PlatformHandle|s (i.e., FDs), which were
|
| +// sent before the "inert" data.
|
| +// - Receive the "inert" data from the |MessageInTransit|. Examine its
|
| +// "platform handle table". On POSIX, match its entries with the buffered
|
| +// |PlatformHandle|s, which were previously received. On Windows, do what's
|
| +// necessary to obtain |PlatformHandle|s (e.g.: i. if the sender is fully
|
| +// trusted and able to duplicate handle into the receiver, then just pick
|
| +// out the |HANDLE| value; ii. if the receiver is fully trusted and able to
|
| +// duplicate handles from the receiver, do the |DuplicateHandle()|; iii.
|
| +// otherwise, talk to a broker to get handles). Reattach all the
|
| +// |PlatformHandle|s to the |MessageInTransit|.
|
| +// - For each entry in the "handle table", use serialized dispatcher data to
|
| +// reconstitute a dispatcher, taking ownership of associated
|
| +// |PlatformHandle|s (and detaching them). Attach these dispatchers to the
|
| +// |MessageInTransit|.
|
| +// - At this point, the |MessageInTransit| consists of its main buffer
|
| +// (primarily the data payload) and the attached dispatchers; the
|
| +// |TransportData| can be discarded.
|
| +// - When |MojoReadMessage()| is to give data to the application, attach the
|
| +// dispatchers to the (global, "core") handle table, getting handles; give
|
| +// the application the data payload and these handles.
|
| +//
|
| +// TODO(vtl): Everything above involving |PlatformHandle|s.
|
| +class MOJO_SYSTEM_IMPL_EXPORT TransportData {
|
| + public:
|
| + // The maximum size of a single serialized dispatcher. This must be a multiple
|
| + // of |kMessageAlignment|.
|
| + static const size_t kMaxSerializedDispatcherSize = 10000;
|
| +
|
| + // The maximum number of platform handles to attach for a single serialized
|
| + // dispatcher.
|
| + static const size_t kMaxSerializedDispatcherPlatformHandles = 2;
|
| +
|
| + TransportData(
|
| + scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers,
|
| + Channel* channel);
|
| + ~TransportData();
|
| +
|
| + const void* buffer() const { return buffer_.get(); }
|
| + size_t buffer_size() const { return buffer_size_; }
|
| +
|
| + // Gets attached platform-specific handles; this may return null if there are
|
| + // none. Note that the caller may mutate the set of platform-specific handles.
|
| + std::vector<embedder::PlatformHandle>* platform_handles() {
|
| + return platform_handles_.get();
|
| + }
|
| +
|
| + // Returns true if there are platform-specific handles attached.
|
| + bool has_platform_handles() const {
|
| + return platform_handles_ && !platform_handles_->empty();
|
| + }
|
| +
|
| + // Receive-side functions:
|
| +
|
| + // Checks if the given buffer (from the "wire") looks like a valid
|
| + // |TransportData| buffer. (Should only be called if |buffer_size| is
|
| + // nonzero.) Returns null if valid, and a pointer to a human-readable error
|
| + // message (for debug/logging purposes) on error. Note: This checks the
|
| + // validity of the handle table entries (i.e., does range checking), but does
|
| + // not check that the validity of the actual serialized dispatcher
|
| + // information.
|
| + static const char* ValidateBuffer(const void* buffer, size_t buffer_size);
|
| +
|
| + // Deserializes dispatchers from the given (serialized) transport data buffer
|
| + // (typically from a |MessageInTransit::View|). |buffer| should be non-null
|
| + // and |buffer_size| should be nonzero.
|
| + static scoped_ptr<std::vector<scoped_refptr<Dispatcher> > >
|
| + DeserializeDispatchersFromBuffer(const void* buffer,
|
| + size_t buffer_size,
|
| + Channel* channel);
|
| +
|
| + private:
|
| + // To allow us to make compile-assertions about |Header|, etc. in the .cc
|
| + // file.
|
| + struct PrivateStructForCompileAsserts;
|
| +
|
| + // Header for the "secondary buffer"/"transport data". Must be a multiple of
|
| + // |MessageInTransit::kMessageAlignment| in size. Must be POD.
|
| + struct Header {
|
| + uint32_t num_handles;
|
| + // TODO(vtl): Not used yet:
|
| + uint32_t platform_handle_table_offset;
|
| + uint32_t num_platform_handles;
|
| + uint32_t unused;
|
| + };
|
| +
|
| + struct HandleTableEntry {
|
| + int32_t type; // From |Dispatcher::Type| (|kTypeUnknown| for "invalid").
|
| + uint32_t offset; // Relative to the start of the "secondary buffer".
|
| + uint32_t size; // (Not including any padding.)
|
| + uint32_t unused;
|
| + };
|
| +
|
| + // The maximum possible size of a valid transport data buffer.
|
| + static const size_t kMaxBufferSize;
|
| +
|
| + // The maximum total number of platform handles that may be attached.
|
| + static const size_t kMaxPlatformHandles;
|
| +
|
| + size_t buffer_size_;
|
| + scoped_ptr<char, base::AlignedFreeDeleter> buffer_; // Never null.
|
| +
|
| + // Any platform-specific handles attached to this message (for inter-process
|
| + // transport). The vector (if any) owns the handles that it contains (and is
|
| + // responsible for closing them).
|
| + // TODO(vtl): With C++11, change it to a vector of |ScopedPlatformHandles|.
|
| + scoped_ptr<std::vector<embedder::PlatformHandle> > platform_handles_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TransportData);
|
| +};
|
| +
|
| +} // namespace system
|
| +} // namespace mojo
|
| +
|
| +#endif // MOJO_SYSTEM_TRANSPORT_DATA_H_
|
|
|