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 |