1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_EDK_EMBEDDER_PLATFORM_SHARED_BUFFER_H_ 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_EDK_EMBEDDER_PLATFORM_SHARED_BUFFER_H_ 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stddef.h> 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <memory> 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h" 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/ref_counted.h" 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/shared_memory.h" 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/shared_memory_handle.h" 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/synchronization/lock.h" 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/embedder/scoped_platform_handle.h" 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/system_impl_export.h" 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo { 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk { 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass PlatformSharedBufferMapping; 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// |PlatformSharedBuffer| is a thread-safe, ref-counted wrapper around 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// OS-specific shared memory. It has the following features: 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// - A |PlatformSharedBuffer| simply represents a piece of shared memory that 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// *may* be mapped and *may* be shared to another process. 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// - A single |PlatformSharedBuffer| may be mapped multiple times. The 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// lifetime of the mapping (owned by |PlatformSharedBufferMapping|) is 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// separate from the lifetime of the |PlatformSharedBuffer|. 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// - Sizes/offsets (of the shared memory and mappings) are arbitrary, and not 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// restricted by page size. However, more memory may actually be mapped than 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// requested. 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MOJO_SYSTEM_IMPL_EXPORT PlatformSharedBuffer 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez : public base::RefCountedThreadSafe<PlatformSharedBuffer> { 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public: 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Creates a shared buffer of size |num_bytes| bytes (initially zero-filled). 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // |num_bytes| must be nonzero. Returns null on failure. 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static PlatformSharedBuffer* Create(size_t num_bytes); 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Creates a shared buffer of size |num_bytes| from the existing platform 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // handle |platform_handle|. Returns null on failure. 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static PlatformSharedBuffer* CreateFromPlatformHandle( 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t num_bytes, 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool read_only, 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ScopedPlatformHandle platform_handle); 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Creates a shared buffer of size |num_bytes| from the existing pair of 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // read/write and read-only handles |rw_platform_handle| and 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // |ro_platform_handle|. Returns null on failure. 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static PlatformSharedBuffer* CreateFromPlatformHandlePair( 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t num_bytes, 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ScopedPlatformHandle rw_platform_handle, 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ScopedPlatformHandle ro_platform_handle); 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Creates a shared buffer of size |num_bytes| from the existing shared memory 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // handle |handle|. 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static PlatformSharedBuffer* CreateFromSharedMemoryHandle( 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t num_bytes, 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool read_only, 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::SharedMemoryHandle handle); 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Gets the size of shared buffer (in number of bytes). 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t GetNumBytes() const; 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns whether this shared buffer is read-only. 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool IsReadOnly() const; 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Maps (some) of the shared buffer into memory; [|offset|, |offset + length|] 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // must be contained in [0, |num_bytes|], and |length| must be at least 1. 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Returns null on failure. 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::unique_ptr<PlatformSharedBufferMapping> Map(size_t offset, 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t length); 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Checks if |offset| and |length| are valid arguments. 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool IsValidMap(size_t offset, size_t length); 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Like |Map()|, but doesn't check its arguments (which should have been 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // preflighted using |IsValidMap()|). 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::unique_ptr<PlatformSharedBufferMapping> MapNoCheck(size_t offset, 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t length); 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Duplicates the underlying platform handle and passes it to the caller. 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ScopedPlatformHandle DuplicatePlatformHandle(); 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Duplicates the underlying shared memory handle and passes it to the caller. 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::SharedMemoryHandle DuplicateSharedMemoryHandle(); 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Passes the underlying platform handle to the caller. This should only be 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // called if there's a unique reference to this object (owned by the caller). 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // After calling this, this object should no longer be used, but should only 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // be disposed of. 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ScopedPlatformHandle PassPlatformHandle(); 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Create and return a read-only duplicate of this shared buffer. If this 97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // shared buffer isn't capable of returning a read-only duplicate, then 98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // nullptr will be returned. 99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez PlatformSharedBuffer* CreateReadOnlyDuplicate(); 100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private: 102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez friend class base::RefCountedThreadSafe<PlatformSharedBuffer>; 103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez PlatformSharedBuffer(size_t num_bytes, bool read_only); 105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ~PlatformSharedBuffer(); 106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // This is called by |Create()| before this object is given to anyone. 108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool Init(); 109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // This is like |Init()|, but for |CreateFromPlatformHandle()|. (Note: It 111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // should verify that |platform_handle| is an appropriate handle for the 112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // claimed |num_bytes_|.) 113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool InitFromPlatformHandle(ScopedPlatformHandle platform_handle); 114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool InitFromPlatformHandlePair(ScopedPlatformHandle rw_platform_handle, 116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ScopedPlatformHandle ro_platform_handle); 117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void InitFromSharedMemoryHandle(base::SharedMemoryHandle handle); 119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const size_t num_bytes_; 121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const bool read_only_; 122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::Lock lock_; 124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::unique_ptr<base::SharedMemory> shared_memory_; 125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // A separate read-only shared memory for platforms that need it (i.e. Linux 127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // with sync broker). 128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::unique_ptr<base::SharedMemory> ro_shared_memory_; 129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DISALLOW_COPY_AND_ASSIGN(PlatformSharedBuffer); 131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}; 132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// A mapping of a |PlatformSharedBuffer| (compararable to a "file view" in 134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Windows); see above. Created by |PlatformSharedBuffer::Map()|. Automatically 135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// unmaps memory on destruction. 136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// 137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Mappings are NOT thread-safe. 138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// 139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Note: This is an entirely separate class (instead of 140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// |PlatformSharedBuffer::Mapping|) so that it can be forward-declared. 141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MOJO_SYSTEM_IMPL_EXPORT PlatformSharedBufferMapping { 142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public: 143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ~PlatformSharedBufferMapping(); 144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void* GetBase() const; 146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t GetLength() const; 147645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 148645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private: 149645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez friend class PlatformSharedBuffer; 150645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 151645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez PlatformSharedBufferMapping(base::SharedMemoryHandle handle, 152645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool read_only, 153645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t offset, 154645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t length) 155645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez : offset_(offset), 156645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez length_(length), 157645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base_(nullptr), 158645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez shared_memory_(handle, read_only) {} 159645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 160645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool Map(); 161645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void Unmap(); 162645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 163645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const size_t offset_; 164645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const size_t length_; 165645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void* base_; 166645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 167645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Since mapping life cycles are separate from PlatformSharedBuffer and a 168645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // buffer can be mapped multiple times, we have our own SharedMemory object 169645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // created from a duplicate handle. 170645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::SharedMemory shared_memory_; 171645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 172645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DISALLOW_COPY_AND_ASSIGN(PlatformSharedBufferMapping); 173645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}; 174645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 175645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace edk 176645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace mojo 177645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 178645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif // MOJO_EDK_EMBEDDER_PLATFORM_SHARED_BUFFER_H_ 179