1 // Copyright 2014 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_RAW_SHARED_BUFFER_H_ 6 #define MOJO_SYSTEM_RAW_SHARED_BUFFER_H_ 7 8 #include <stddef.h> 9 10 #include "base/macros.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "mojo/embedder/scoped_platform_handle.h" 14 #include "mojo/system/system_impl_export.h" 15 16 namespace mojo { 17 namespace system { 18 19 class RawSharedBufferMapping; 20 21 // |RawSharedBuffer| is a thread-safe, ref-counted wrapper around OS-specific 22 // shared memory. It has the following features: 23 // - A |RawSharedBuffer| simply represents a piece of shared memory that *may* 24 // be mapped and *may* be shared to another process. 25 // - A single |RawSharedBuffer| may be mapped multiple times. The lifetime of 26 // the mapping (owned by |RawSharedBufferMapping|) is separate from the 27 // lifetime of the |RawSharedBuffer|. 28 // - Sizes/offsets (of the shared memory and mappings) are arbitrary, and not 29 // restricted by page size. However, more memory may actually be mapped than 30 // requested. 31 // 32 // It currently does NOT support the following: 33 // - Sharing read-only. (This will probably eventually be supported.) 34 // 35 // TODO(vtl): Rectify this with |base::SharedMemory|. 36 class MOJO_SYSTEM_IMPL_EXPORT RawSharedBuffer 37 : public base::RefCountedThreadSafe<RawSharedBuffer> { 38 public: 39 // Creates a shared buffer of size |num_bytes| bytes (initially zero-filled). 40 // |num_bytes| must be nonzero. Returns null on failure. 41 static RawSharedBuffer* Create(size_t num_bytes); 42 43 static RawSharedBuffer* CreateFromPlatformHandle( 44 size_t num_bytes, 45 embedder::ScopedPlatformHandle platform_handle); 46 47 // Maps (some) of the shared buffer into memory; [|offset|, |offset + length|] 48 // must be contained in [0, |num_bytes|], and |length| must be at least 1. 49 // Returns null on failure. 50 scoped_ptr<RawSharedBufferMapping> Map(size_t offset, size_t length); 51 52 // Checks if |offset| and |length| are valid arguments. 53 bool IsValidMap(size_t offset, size_t length); 54 55 // Like |Map()|, but doesn't check its arguments (which should have been 56 // preflighted using |IsValidMap()|). 57 scoped_ptr<RawSharedBufferMapping> MapNoCheck(size_t offset, size_t length); 58 59 // Duplicates the underlying platform handle and passes it to the caller. 60 embedder::ScopedPlatformHandle DuplicatePlatformHandle(); 61 62 // Passes the underlying platform handle to the caller. This should only be 63 // called if there's a unique reference to this object (owned by the caller). 64 // After calling this, this object should no longer be used, but should only 65 // be disposed of. 66 embedder::ScopedPlatformHandle PassPlatformHandle(); 67 num_bytes()68 size_t num_bytes() const { return num_bytes_; } 69 70 private: 71 friend class base::RefCountedThreadSafe<RawSharedBuffer>; 72 73 explicit RawSharedBuffer(size_t num_bytes); 74 ~RawSharedBuffer(); 75 76 // Implemented in raw_shared_buffer_{posix,win}.cc: 77 78 // This is called by |Create()| before this object is given to anyone. 79 bool Init(); 80 81 // This is like |Init()|, but for |CreateFromPlatformHandle()|. (Note: It 82 // should verify that |platform_handle| is an appropriate handle for the 83 // claimed |num_bytes_|.) 84 bool InitFromPlatformHandle(embedder::ScopedPlatformHandle platform_handle); 85 86 // The platform-dependent part of |Map()|; doesn't check arguments. 87 scoped_ptr<RawSharedBufferMapping> MapImpl(size_t offset, size_t length); 88 89 const size_t num_bytes_; 90 91 // This is set in |Init()|/|InitFromPlatformHandle()| and never modified 92 // (except by |PassPlatformHandle()|; see the comments above its declaration), 93 // hence does not need to be protected by a lock. 94 embedder::ScopedPlatformHandle handle_; 95 96 DISALLOW_COPY_AND_ASSIGN(RawSharedBuffer); 97 }; 98 99 // A mapping of a |RawSharedBuffer| (compararable to a "file view" in Windows); 100 // see above. Created by |RawSharedBuffer::Map()|. Automatically unmaps memory 101 // on destruction. 102 // 103 // Mappings are NOT thread-safe. 104 // 105 // Note: This is an entirely separate class (instead of 106 // |RawSharedBuffer::Mapping|) so that it can be forward-declared. 107 class MOJO_SYSTEM_IMPL_EXPORT RawSharedBufferMapping { 108 public: ~RawSharedBufferMapping()109 ~RawSharedBufferMapping() { Unmap(); } 110 base()111 void* base() const { return base_; } length()112 size_t length() const { return length_; } 113 114 private: 115 friend class RawSharedBuffer; 116 RawSharedBufferMapping(void * base,size_t length,void * real_base,size_t real_length)117 RawSharedBufferMapping(void* base, 118 size_t length, 119 void* real_base, 120 size_t real_length) 121 : base_(base), length_(length), 122 real_base_(real_base), real_length_(real_length) {} 123 void Unmap(); 124 125 void* const base_; 126 const size_t length_; 127 128 void* const real_base_; 129 const size_t real_length_; 130 131 DISALLOW_COPY_AND_ASSIGN(RawSharedBufferMapping); 132 }; 133 134 } // namespace system 135 } // namespace mojo 136 137 #endif // MOJO_SYSTEM_RAW_SHARED_BUFFER_H_ 138