| Index: mojo/edk/system/data_pipe.h
|
| diff --git a/mojo/edk/system/data_pipe.h b/mojo/edk/system/data_pipe.h
|
| index d2b90bf1ab6a138f26dd358d7d03c7ace4f3bf94..21dcfb2ab1fa7cbf1f3fb619e81226c03ec683d8 100644
|
| --- a/mojo/edk/system/data_pipe.h
|
| +++ b/mojo/edk/system/data_pipe.h
|
| @@ -6,9 +6,14 @@
|
| #define MOJO_EDK_SYSTEM_DATA_PIPE_H_
|
|
|
| #include <stddef.h>
|
| +#include <vector>
|
|
|
| +#include "base/callback_forward.h"
|
| #include "base/compiler_specific.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/ref_counted.h"
|
| #include "mojo/edk/embedder/platform_handle_vector.h"
|
| +#include "mojo/edk/embedder/platform_shared_buffer.h"
|
| #include "mojo/edk/embedder/scoped_platform_handle.h"
|
| #include "mojo/edk/system/system_impl_export.h"
|
| #include "mojo/public/c/system/data_pipe.h"
|
| @@ -19,9 +24,19 @@ namespace mojo {
|
| namespace edk {
|
| class RawChannel;
|
|
|
| +enum DataPipeCommand : uint32_t { DATA_WRITTEN, DATA_READ };
|
| +
|
| +struct MOJO_ALIGNAS(8) DataPipeCommandHeader {
|
| + DataPipeCommand command;
|
| + uint32_t num_bytes;
|
| +};
|
| +
|
| // Shared code between DataPipeConsumerDispatcher and
|
| -// DataPipeProducerDispatcher.
|
| -class MOJO_SYSTEM_IMPL_EXPORT DataPipe {
|
| +// DataPipeProducerDispatcher. This class is not thread safe -- all locking must
|
| +// be performed by the caller. This class is only intended to be used as a
|
| +// writer or a reader, not both.
|
| +class MOJO_SYSTEM_IMPL_EXPORT DataPipe final
|
| + : public base::RefCountedThreadSafe<DataPipe> {
|
| public:
|
| // The default options for |MojoCreateDataPipe()|. (Real uses should obtain
|
| // this via |ValidateCreateOptions()| with a null |in_options|; this is
|
| @@ -37,26 +52,97 @@ class MOJO_SYSTEM_IMPL_EXPORT DataPipe {
|
| const MojoCreateDataPipeOptions* in_options,
|
| MojoCreateDataPipeOptions* out_options);
|
|
|
| + explicit DataPipe(const MojoCreateDataPipeOptions& options);
|
| +
|
| + void Init();
|
| +
|
| // Helper methods used by DataPipeConsumerDispatcher and
|
| // DataPipeProducerDispatcher for serialization and deserialization.
|
| - static void StartSerialize(bool have_channel_handle,
|
| - bool have_shared_memory,
|
| - size_t* max_size,
|
| - size_t* max_platform_handles);
|
| - static void EndSerialize(const MojoCreateDataPipeOptions& options,
|
| - ScopedPlatformHandle channel_handle,
|
| - ScopedPlatformHandle shared_memory_handle,
|
| - size_t shared_memory_size,
|
| - void* destination,
|
| - size_t* actual_size,
|
| - PlatformHandleVector* platform_handles);
|
| - static ScopedPlatformHandle Deserialize(
|
| + void StartSerialize(size_t* max_size, size_t* max_platform_handles);
|
| + void EndSerialize(void* destination,
|
| + size_t* actual_size,
|
| + PlatformHandleVector* platform_handles);
|
| + static scoped_refptr<DataPipe> Deserialize(
|
| const void* source,
|
| size_t size,
|
| - PlatformHandleVector* platform_handles,
|
| - MojoCreateDataPipeOptions* options,
|
| - ScopedPlatformHandle* shared_memory_handle,
|
| - size_t* shared_memory_size);
|
| + PlatformHandleVector* platform_handles);
|
| +
|
| + // Returns the number of readable or writable bytes. If there is no valid
|
| + // shared buffer, returns 0.
|
| + uint32_t GetReadableBytes() const;
|
| + uint32_t GetWritableBytes() const;
|
| +
|
| + // Two phase reads and writes. Note that since returned memory has to be
|
| + // contiguous, these may return less than the values returned by
|
| + // |GetReadableBytes| / |GetWritableBytes|.
|
| + void* GetWriteBuffer(uint32_t* num_bytes);
|
| + const void* GetReadBuffer(uint32_t* num_bytes);
|
| +
|
| + // Normal reads and writes. Will return false if they can't read or write
|
| + // all the data given.
|
| + bool WriteDataIntoSharedBuffer(const void* data, uint32_t num_bytes);
|
| + bool ReadDataFromSharedBuffer(void* buf, uint32_t num_bytes);
|
| +
|
| + // Notify other end of a read or write. Returns false if the other side was
|
| + // closed (on a RawChannel error).
|
| + bool NotifyWrite(uint32_t num_bytes);
|
| + bool NotifyRead(uint32_t num_bytes);
|
| +
|
| + // Reading and writing are split into three parts: 1. reading / writing the
|
| + // data, telling the other side what we did, and updating the ring buffer to
|
| + // reflect what we did. The functions |UpdateFromRead| and |UpdateFromWrite|
|
| + // update the ring buffer state.
|
| + void UpdateFromRead(uint32_t num_bytes);
|
| + void UpdateFromWrite(uint32_t num_bytes);
|
| +
|
| + RawChannel* channel() { return channel_; }
|
| + void set_channel(RawChannel* channel) {
|
| + DCHECK(!channel_);
|
| + channel_ = channel;
|
| + }
|
| + void set_shared_buffer(scoped_refptr<PlatformSharedBuffer> shared_buffer) {
|
| + shared_buffer_ = shared_buffer;
|
| + }
|
| + const MojoCreateDataPipeOptions& options() { return options_; }
|
| +
|
| + // Returns whether readable or writable state changed.
|
| + bool ProcessCommand(const DataPipeCommandHeader& command,
|
| + ScopedPlatformHandleVectorPtr platform_handles);
|
| +
|
| + // Shuts down the channel, and releases the shared buffer.
|
| + void Shutdown();
|
| +
|
| + // Named after |CreateEquivalentDispatcherAndCloseImplNoLock|. This will
|
| + // Release() the RawChannel and save its returned read and write buffer, then
|
| + // swap ourselves into |out|.
|
| + void CreateEquivalentAndClose(DataPipe* out);
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<DataPipe>;
|
| + ~DataPipe();
|
| +
|
| + uint8_t* GetSharedBufferBase();
|
| + // Releases the raw channel.
|
| + void Serialize();
|
| +
|
| + RawChannel* channel_;
|
| +
|
| + MojoCreateDataPipeOptions options_;
|
| +
|
| + // True if we've released the channel because we're about to get serialized
|
| + // and transported. We also store the channel's read and write buffer, and
|
| + // handle.
|
| + bool channel_released_;
|
| + std::vector<char> serialized_read_buffer_;
|
| + std::vector<char> serialized_write_buffer_;
|
| + ScopedPlatformHandle serialized_channel_handle_;
|
| +
|
| + scoped_refptr<PlatformSharedBuffer> shared_buffer_;
|
| + // Keep the full mapping of the shared buffer around so we don't have to
|
| + // recreate it.
|
| + scoped_ptr<PlatformSharedBufferMapping> mapping_;
|
| + uint32_t ring_buffer_start_;
|
| + uint32_t ring_buffer_size_;
|
| };
|
|
|
| } // namespace edk
|
|
|