| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/embedder/platform_shared_buffer.h" | 5 #include "mojo/edk/embedder/platform_shared_buffer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 } | 37 } |
| 38 #endif | 38 #endif |
| 39 } | 39 } |
| 40 | 40 |
| 41 } // namespace | 41 } // namespace |
| 42 | 42 |
| 43 // static | 43 // static |
| 44 PlatformSharedBuffer* PlatformSharedBuffer::Create(size_t num_bytes) { | 44 PlatformSharedBuffer* PlatformSharedBuffer::Create(size_t num_bytes) { |
| 45 DCHECK_GT(num_bytes, 0u); | 45 DCHECK_GT(num_bytes, 0u); |
| 46 | 46 |
| 47 PlatformSharedBuffer* rv = new PlatformSharedBuffer(num_bytes); | 47 PlatformSharedBuffer* rv = new PlatformSharedBuffer(num_bytes, false); |
| 48 if (!rv->Init()) { | 48 if (!rv->Init()) { |
| 49 // We can't just delete it directly, due to the "in destructor" (debug) | 49 // We can't just delete it directly, due to the "in destructor" (debug) |
| 50 // check. | 50 // check. |
| 51 scoped_refptr<PlatformSharedBuffer> deleter(rv); | 51 scoped_refptr<PlatformSharedBuffer> deleter(rv); |
| 52 return nullptr; | 52 return nullptr; |
| 53 } | 53 } |
| 54 | 54 |
| 55 return rv; | 55 return rv; |
| 56 } | 56 } |
| 57 | 57 |
| 58 // static | 58 // static |
| 59 PlatformSharedBuffer* PlatformSharedBuffer::CreateFromPlatformHandle( | 59 PlatformSharedBuffer* PlatformSharedBuffer::CreateFromPlatformHandle( |
| 60 size_t num_bytes, | 60 size_t num_bytes, |
| 61 bool read_only, |
| 61 ScopedPlatformHandle platform_handle) { | 62 ScopedPlatformHandle platform_handle) { |
| 62 DCHECK_GT(num_bytes, 0u); | 63 DCHECK_GT(num_bytes, 0u); |
| 63 | 64 |
| 64 PlatformSharedBuffer* rv = new PlatformSharedBuffer(num_bytes); | 65 PlatformSharedBuffer* rv = new PlatformSharedBuffer(num_bytes, read_only); |
| 65 if (!rv->InitFromPlatformHandle(std::move(platform_handle))) { | 66 if (!rv->InitFromPlatformHandle(std::move(platform_handle))) { |
| 66 // We can't just delete it directly, due to the "in destructor" (debug) | 67 // We can't just delete it directly, due to the "in destructor" (debug) |
| 67 // check. | 68 // check. |
| 68 scoped_refptr<PlatformSharedBuffer> deleter(rv); | 69 scoped_refptr<PlatformSharedBuffer> deleter(rv); |
| 69 return nullptr; | 70 return nullptr; |
| 70 } | 71 } |
| 71 | 72 |
| 72 return rv; | 73 return rv; |
| 73 } | 74 } |
| 74 | 75 |
| 75 // static | 76 // static |
| 76 PlatformSharedBuffer* PlatformSharedBuffer::CreateFromSharedMemoryHandle( | 77 PlatformSharedBuffer* PlatformSharedBuffer::CreateFromSharedMemoryHandle( |
| 77 size_t num_bytes, | 78 size_t num_bytes, |
| 78 bool read_only, | 79 bool read_only, |
| 79 base::SharedMemoryHandle handle) { | 80 base::SharedMemoryHandle handle) { |
| 80 DCHECK_GT(num_bytes, 0u); | 81 DCHECK_GT(num_bytes, 0u); |
| 81 DCHECK(!read_only); | |
| 82 | 82 |
| 83 PlatformSharedBuffer* rv = new PlatformSharedBuffer(num_bytes); | 83 PlatformSharedBuffer* rv = new PlatformSharedBuffer(num_bytes, read_only); |
| 84 rv->InitFromSharedMemoryHandle(handle); | 84 rv->InitFromSharedMemoryHandle(handle); |
| 85 | 85 |
| 86 return rv; | 86 return rv; |
| 87 } | 87 } |
| 88 | 88 |
| 89 size_t PlatformSharedBuffer::GetNumBytes() const { | 89 size_t PlatformSharedBuffer::GetNumBytes() const { |
| 90 return num_bytes_; | 90 return num_bytes_; |
| 91 } | 91 } |
| 92 | 92 |
| 93 bool PlatformSharedBuffer::IsReadOnly() const { |
| 94 return read_only_; |
| 95 } |
| 96 |
| 93 scoped_ptr<PlatformSharedBufferMapping> PlatformSharedBuffer::Map( | 97 scoped_ptr<PlatformSharedBufferMapping> PlatformSharedBuffer::Map( |
| 94 size_t offset, | 98 size_t offset, |
| 95 size_t length) { | 99 size_t length) { |
| 96 if (!IsValidMap(offset, length)) | 100 if (!IsValidMap(offset, length)) |
| 97 return nullptr; | 101 return nullptr; |
| 98 | 102 |
| 99 return MapNoCheck(offset, length); | 103 return MapNoCheck(offset, length); |
| 100 } | 104 } |
| 101 | 105 |
| 102 bool PlatformSharedBuffer::IsValidMap(size_t offset, size_t length) { | 106 bool PlatformSharedBuffer::IsValidMap(size_t offset, size_t length) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 118 DCHECK(shared_memory_); | 122 DCHECK(shared_memory_); |
| 119 base::SharedMemoryHandle handle; | 123 base::SharedMemoryHandle handle; |
| 120 { | 124 { |
| 121 base::AutoLock locker(lock_); | 125 base::AutoLock locker(lock_); |
| 122 handle = base::SharedMemory::DuplicateHandle(shared_memory_->handle()); | 126 handle = base::SharedMemory::DuplicateHandle(shared_memory_->handle()); |
| 123 } | 127 } |
| 124 if (handle == base::SharedMemory::NULLHandle()) | 128 if (handle == base::SharedMemory::NULLHandle()) |
| 125 return nullptr; | 129 return nullptr; |
| 126 | 130 |
| 127 scoped_ptr<PlatformSharedBufferMapping> mapping( | 131 scoped_ptr<PlatformSharedBufferMapping> mapping( |
| 128 new PlatformSharedBufferMapping(handle, offset, length)); | 132 new PlatformSharedBufferMapping(handle, read_only_, offset, length)); |
| 129 if (mapping->Map()) | 133 if (mapping->Map()) |
| 130 return make_scoped_ptr(mapping.release()); | 134 return make_scoped_ptr(mapping.release()); |
| 131 | 135 |
| 132 return nullptr; | 136 return nullptr; |
| 133 } | 137 } |
| 134 | 138 |
| 135 ScopedPlatformHandle PlatformSharedBuffer::DuplicatePlatformHandle() { | 139 ScopedPlatformHandle PlatformSharedBuffer::DuplicatePlatformHandle() { |
| 136 DCHECK(shared_memory_); | 140 DCHECK(shared_memory_); |
| 137 base::SharedMemoryHandle handle; | 141 base::SharedMemoryHandle handle; |
| 138 { | 142 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 157 return handle; | 161 return handle; |
| 158 } | 162 } |
| 159 | 163 |
| 160 base::SharedMemoryHandle PlatformSharedBuffer::DuplicateSharedMemoryHandle() { | 164 base::SharedMemoryHandle PlatformSharedBuffer::DuplicateSharedMemoryHandle() { |
| 161 DCHECK(shared_memory_); | 165 DCHECK(shared_memory_); |
| 162 | 166 |
| 163 base::AutoLock locker(lock_); | 167 base::AutoLock locker(lock_); |
| 164 return base::SharedMemory::DuplicateHandle(shared_memory_->handle()); | 168 return base::SharedMemory::DuplicateHandle(shared_memory_->handle()); |
| 165 } | 169 } |
| 166 | 170 |
| 167 PlatformSharedBuffer::PlatformSharedBuffer(size_t num_bytes) | 171 PlatformSharedBuffer* PlatformSharedBuffer::CreateReadOnlyDuplicate() { |
| 168 : num_bytes_(num_bytes) {} | 172 DCHECK(shared_memory_); |
| 173 base::SharedMemoryHandle handle; |
| 174 bool success; |
| 175 { |
| 176 base::AutoLock locker(lock_); |
| 177 success = shared_memory_->ShareReadOnlyToProcess( |
| 178 base::GetCurrentProcessHandle(), &handle); |
| 179 } |
| 180 if (!success || handle == base::SharedMemory::NULLHandle()) |
| 181 return nullptr; |
| 182 |
| 183 return CreateFromSharedMemoryHandle(num_bytes_, true, handle); |
| 184 } |
| 185 |
| 186 PlatformSharedBuffer::PlatformSharedBuffer(size_t num_bytes, bool read_only) |
| 187 : num_bytes_(num_bytes), read_only_(read_only) {} |
| 169 | 188 |
| 170 PlatformSharedBuffer::~PlatformSharedBuffer() {} | 189 PlatformSharedBuffer::~PlatformSharedBuffer() {} |
| 171 | 190 |
| 172 bool PlatformSharedBuffer::Init() { | 191 bool PlatformSharedBuffer::Init() { |
| 173 DCHECK(!shared_memory_); | 192 DCHECK(!shared_memory_); |
| 193 DCHECK(!read_only_); |
| 174 | 194 |
| 175 base::SharedMemoryCreateOptions options; | 195 base::SharedMemoryCreateOptions options; |
| 176 options.size = num_bytes_; | 196 options.size = num_bytes_; |
| 197 // By default, we can share as read-only. |
| 198 options.share_read_only = true; |
| 177 #if defined(OS_MACOSX) && !defined(OS_IOS) | 199 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 178 options.type = base::SharedMemoryHandle::MACH; | 200 options.type = base::SharedMemoryHandle::MACH; |
| 179 #endif | 201 #endif |
| 180 | 202 |
| 181 shared_memory_.reset(new base::SharedMemory); | 203 shared_memory_.reset(new base::SharedMemory); |
| 182 return shared_memory_->Create(options); | 204 return shared_memory_->Create(options); |
| 183 } | 205 } |
| 184 | 206 |
| 185 bool PlatformSharedBuffer::InitFromPlatformHandle( | 207 bool PlatformSharedBuffer::InitFromPlatformHandle( |
| 186 ScopedPlatformHandle platform_handle) { | 208 ScopedPlatformHandle platform_handle) { |
| 187 DCHECK(!shared_memory_); | 209 DCHECK(!shared_memory_); |
| 188 | 210 |
| 189 #if defined(OS_WIN) | 211 #if defined(OS_WIN) |
| 190 base::SharedMemoryHandle handle(platform_handle.release().handle, | 212 base::SharedMemoryHandle handle(platform_handle.release().handle, |
| 191 base::GetCurrentProcId()); | 213 base::GetCurrentProcId()); |
| 192 #elif defined(OS_MACOSX) && !defined(OS_IOS) | 214 #elif defined(OS_MACOSX) && !defined(OS_IOS) |
| 193 base::SharedMemoryHandle handle; | 215 base::SharedMemoryHandle handle; |
| 194 if (platform_handle.get().type == PlatformHandle::Type::MACH) { | 216 if (platform_handle.get().type == PlatformHandle::Type::MACH) { |
| 195 handle = base::SharedMemoryHandle( | 217 handle = base::SharedMemoryHandle( |
| 196 platform_handle.release().port, num_bytes_, base::GetCurrentProcId()); | 218 platform_handle.release().port, num_bytes_, base::GetCurrentProcId()); |
| 197 } else { | 219 } else { |
| 198 handle = base::SharedMemoryHandle(platform_handle.release().handle, false); | 220 handle = base::SharedMemoryHandle(platform_handle.release().handle, false); |
| 199 } | 221 } |
| 200 #else | 222 #else |
| 201 base::SharedMemoryHandle handle(platform_handle.release().handle, false); | 223 base::SharedMemoryHandle handle(platform_handle.release().handle, false); |
| 202 #endif | 224 #endif |
| 203 | 225 |
| 204 shared_memory_.reset(new base::SharedMemory(handle, false)); | 226 shared_memory_.reset(new base::SharedMemory(handle, read_only_)); |
| 205 return true; | 227 return true; |
| 206 } | 228 } |
| 207 | 229 |
| 208 void PlatformSharedBuffer::InitFromSharedMemoryHandle( | 230 void PlatformSharedBuffer::InitFromSharedMemoryHandle( |
| 209 base::SharedMemoryHandle handle) { | 231 base::SharedMemoryHandle handle) { |
| 210 DCHECK(!shared_memory_); | 232 DCHECK(!shared_memory_); |
| 211 | 233 |
| 212 // TODO(crbug.com/556587): Support read-only handles. | 234 shared_memory_.reset(new base::SharedMemory(handle, read_only_)); |
| 213 shared_memory_.reset(new base::SharedMemory(handle, false)); | |
| 214 } | 235 } |
| 215 | 236 |
| 216 PlatformSharedBufferMapping::~PlatformSharedBufferMapping() { | 237 PlatformSharedBufferMapping::~PlatformSharedBufferMapping() { |
| 217 Unmap(); | 238 Unmap(); |
| 218 } | 239 } |
| 219 | 240 |
| 220 void* PlatformSharedBufferMapping::GetBase() const { | 241 void* PlatformSharedBufferMapping::GetBase() const { |
| 221 return base_; | 242 return base_; |
| 222 } | 243 } |
| 223 | 244 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 239 base_ = static_cast<char*>(shared_memory_.memory()) + offset_rounding; | 260 base_ = static_cast<char*>(shared_memory_.memory()) + offset_rounding; |
| 240 return true; | 261 return true; |
| 241 } | 262 } |
| 242 | 263 |
| 243 void PlatformSharedBufferMapping::Unmap() { | 264 void PlatformSharedBufferMapping::Unmap() { |
| 244 shared_memory_.Unmap(); | 265 shared_memory_.Unmap(); |
| 245 } | 266 } |
| 246 | 267 |
| 247 } // namespace edk | 268 } // namespace edk |
| 248 } // namespace mojo | 269 } // namespace mojo |
| OLD | NEW |