OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/memory/shared_memory.h" | 5 #include "base/memory/shared_memory.h" |
6 | 6 |
7 #include <aclapi.h> | 7 #include <aclapi.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 SharedMemory::SharedMemory(const std::wstring& name) | 145 SharedMemory::SharedMemory(const std::wstring& name) |
146 : external_section_(false), | 146 : external_section_(false), |
147 name_(name), | 147 name_(name), |
148 mapped_size_(0), | 148 mapped_size_(0), |
149 memory_(NULL), | 149 memory_(NULL), |
150 read_only_(false), | 150 read_only_(false), |
151 requested_size_(0) {} | 151 requested_size_(0) {} |
152 | 152 |
153 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) | 153 SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only) |
154 : external_section_(true), | 154 : external_section_(true), |
| 155 shm_(handle), |
155 mapped_size_(0), | 156 mapped_size_(0), |
156 memory_(NULL), | 157 memory_(NULL), |
157 read_only_(read_only), | 158 read_only_(read_only), |
158 requested_size_(0) { | 159 requested_size_(0) {} |
159 mapped_file_.Set(handle.GetHandle()); | |
160 } | |
161 | 160 |
162 SharedMemory::~SharedMemory() { | 161 SharedMemory::~SharedMemory() { |
163 Unmap(); | 162 Unmap(); |
164 Close(); | 163 Close(); |
165 } | 164 } |
166 | 165 |
167 // static | 166 // static |
168 bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { | 167 bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { |
169 return handle.IsValid(); | 168 return handle.IsValid(); |
170 } | 169 } |
(...skipping 18 matching lines...) Expand all Loading... |
189 | 188 |
190 bool SharedMemory::CreateAndMapAnonymous(size_t size) { | 189 bool SharedMemory::CreateAndMapAnonymous(size_t size) { |
191 return CreateAnonymous(size) && Map(size); | 190 return CreateAnonymous(size) && Map(size); |
192 } | 191 } |
193 | 192 |
194 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { | 193 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { |
195 // TODO(bsy,sehr): crbug.com/210609 NaCl forces us to round up 64k here, | 194 // TODO(bsy,sehr): crbug.com/210609 NaCl forces us to round up 64k here, |
196 // wasting 32k per mapping on average. | 195 // wasting 32k per mapping on average. |
197 static const size_t kSectionMask = 65536 - 1; | 196 static const size_t kSectionMask = 65536 - 1; |
198 DCHECK(!options.executable); | 197 DCHECK(!options.executable); |
199 DCHECK(!mapped_file_.Get()); | 198 DCHECK(!shm_.IsValid()); |
200 if (options.size == 0) { | 199 if (options.size == 0) { |
201 LogError(SIZE_ZERO, 0); | 200 LogError(SIZE_ZERO, 0); |
202 return false; | 201 return false; |
203 } | 202 } |
204 | 203 |
205 // Check maximum accounting for overflow. | 204 // Check maximum accounting for overflow. |
206 if (options.size > | 205 if (options.size > |
207 static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask) { | 206 static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask) { |
208 LogError(SIZE_TOO_LARGE, 0); | 207 LogError(SIZE_TOO_LARGE, 0); |
209 return false; | 208 return false; |
(...skipping 24 matching lines...) Expand all Loading... |
234 | 233 |
235 // Windows ignores DACLs on certain unnamed objects (like shared sections). | 234 // Windows ignores DACLs on certain unnamed objects (like shared sections). |
236 // So, we generate a random name when we need to enforce read-only. | 235 // So, we generate a random name when we need to enforce read-only. |
237 uint64_t rand_values[4]; | 236 uint64_t rand_values[4]; |
238 RandBytes(&rand_values, sizeof(rand_values)); | 237 RandBytes(&rand_values, sizeof(rand_values)); |
239 name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx", | 238 name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx", |
240 rand_values[0], rand_values[1], | 239 rand_values[0], rand_values[1], |
241 rand_values[2], rand_values[3]); | 240 rand_values[2], rand_values[3]); |
242 } | 241 } |
243 DCHECK(!name_.empty()); | 242 DCHECK(!name_.empty()); |
244 mapped_file_.Set(CreateFileMappingWithReducedPermissions(&sa, rounded_size, | 243 shm_ = SharedMemoryHandle(CreateFileMappingWithReducedPermissions( |
245 name_.c_str())); | 244 &sa, rounded_size, name_.c_str())); |
246 if (!mapped_file_.IsValid()) { | 245 if (!shm_.IsValid()) { |
247 // The error is logged within CreateFileMappingWithReducedPermissions(). | 246 // The error is logged within CreateFileMappingWithReducedPermissions(). |
248 return false; | 247 return false; |
249 } | 248 } |
250 | 249 |
251 requested_size_ = options.size; | 250 requested_size_ = options.size; |
252 | 251 |
253 // Check if the shared memory pre-exists. | 252 // Check if the shared memory pre-exists. |
254 if (GetLastError() == ERROR_ALREADY_EXISTS) { | 253 if (GetLastError() == ERROR_ALREADY_EXISTS) { |
255 // If the file already existed, set requested_size_ to 0 to show that | 254 // If the file already existed, set requested_size_ to 0 to show that |
256 // we don't know the size. | 255 // we don't know the size. |
(...skipping 10 matching lines...) Expand all Loading... |
267 LogError(SUCCESS, ERROR_SUCCESS); | 266 LogError(SUCCESS, ERROR_SUCCESS); |
268 return true; | 267 return true; |
269 } | 268 } |
270 | 269 |
271 bool SharedMemory::Delete(const std::string& name) { | 270 bool SharedMemory::Delete(const std::string& name) { |
272 // intentionally empty -- there is nothing for us to do on Windows. | 271 // intentionally empty -- there is nothing for us to do on Windows. |
273 return true; | 272 return true; |
274 } | 273 } |
275 | 274 |
276 bool SharedMemory::Open(const std::string& name, bool read_only) { | 275 bool SharedMemory::Open(const std::string& name, bool read_only) { |
277 DCHECK(!mapped_file_.Get()); | 276 DCHECK(!shm_.IsValid()); |
278 DWORD access = FILE_MAP_READ | SECTION_QUERY; | 277 DWORD access = FILE_MAP_READ | SECTION_QUERY; |
279 if (!read_only) | 278 if (!read_only) |
280 access |= FILE_MAP_WRITE; | 279 access |= FILE_MAP_WRITE; |
281 name_ = ASCIIToUTF16(name); | 280 name_ = ASCIIToUTF16(name); |
282 read_only_ = read_only; | 281 read_only_ = read_only; |
283 mapped_file_.Set( | 282 shm_ = SharedMemoryHandle( |
284 OpenFileMapping(access, false, name_.empty() ? nullptr : name_.c_str())); | 283 OpenFileMapping(access, false, name_.empty() ? nullptr : name_.c_str())); |
285 if (!mapped_file_.IsValid()) | 284 if (!shm_.IsValid()) |
286 return false; | 285 return false; |
287 // If a name specified assume it's an external section. | 286 // If a name specified assume it's an external section. |
288 if (!name_.empty()) | 287 if (!name_.empty()) |
289 external_section_ = true; | 288 external_section_ = true; |
290 // Note: size_ is not set in this case. | 289 // Note: size_ is not set in this case. |
291 return true; | 290 return true; |
292 } | 291 } |
293 | 292 |
294 bool SharedMemory::MapAt(off_t offset, size_t bytes) { | 293 bool SharedMemory::MapAt(off_t offset, size_t bytes) { |
295 if (!mapped_file_.Get()) | 294 if (!shm_.IsValid()) |
296 return false; | 295 return false; |
297 | 296 |
298 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) | 297 if (bytes > static_cast<size_t>(std::numeric_limits<int>::max())) |
299 return false; | 298 return false; |
300 | 299 |
301 if (memory_) | 300 if (memory_) |
302 return false; | 301 return false; |
303 | 302 |
304 if (external_section_ && !IsSectionSafeToMap(mapped_file_.Get())) | 303 if (external_section_ && !IsSectionSafeToMap(shm_.GetHandle())) |
305 return false; | 304 return false; |
306 | 305 |
307 memory_ = MapViewOfFile( | 306 memory_ = MapViewOfFile( |
308 mapped_file_.Get(), | 307 shm_.GetHandle(), |
309 read_only_ ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE, | 308 read_only_ ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE, |
310 static_cast<uint64_t>(offset) >> 32, static_cast<DWORD>(offset), bytes); | 309 static_cast<uint64_t>(offset) >> 32, static_cast<DWORD>(offset), bytes); |
311 if (memory_ != NULL) { | 310 if (memory_ != NULL) { |
312 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) & | 311 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(memory_) & |
313 (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); | 312 (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); |
314 mapped_size_ = GetMemorySectionSize(memory_); | 313 mapped_size_ = GetMemorySectionSize(memory_); |
315 return true; | 314 return true; |
316 } | 315 } |
317 return false; | 316 return false; |
318 } | 317 } |
319 | 318 |
320 bool SharedMemory::Unmap() { | 319 bool SharedMemory::Unmap() { |
321 if (memory_ == NULL) | 320 if (memory_ == NULL) |
322 return false; | 321 return false; |
323 | 322 |
324 UnmapViewOfFile(memory_); | 323 UnmapViewOfFile(memory_); |
325 memory_ = NULL; | 324 memory_ = NULL; |
326 return true; | 325 return true; |
327 } | 326 } |
328 | 327 |
329 SharedMemoryHandle SharedMemory::GetReadOnlyHandle() { | 328 SharedMemoryHandle SharedMemory::GetReadOnlyHandle() { |
330 HANDLE result; | 329 HANDLE result; |
331 ProcessHandle process = GetCurrentProcess(); | 330 ProcessHandle process = GetCurrentProcess(); |
332 if (!::DuplicateHandle(process, mapped_file_.Get(), process, &result, | 331 if (!::DuplicateHandle(process, shm_.GetHandle(), process, &result, |
333 FILE_MAP_READ | SECTION_QUERY, FALSE, 0)) { | 332 FILE_MAP_READ | SECTION_QUERY, FALSE, 0)) { |
334 return SharedMemoryHandle(); | 333 return SharedMemoryHandle(); |
335 } | 334 } |
336 SharedMemoryHandle handle = SharedMemoryHandle(result); | 335 SharedMemoryHandle handle = SharedMemoryHandle(result); |
337 handle.SetOwnershipPassesToIPC(true); | 336 handle.SetOwnershipPassesToIPC(true); |
338 return handle; | 337 return handle; |
339 } | 338 } |
340 | 339 |
341 void SharedMemory::Close() { | 340 void SharedMemory::Close() { |
342 mapped_file_.Close(); | 341 if (shm_.IsValid()) { |
| 342 shm_.Close(); |
| 343 shm_ = SharedMemoryHandle(); |
| 344 } |
343 } | 345 } |
344 | 346 |
345 SharedMemoryHandle SharedMemory::handle() const { | 347 SharedMemoryHandle SharedMemory::handle() const { |
346 return SharedMemoryHandle(mapped_file_.Get()); | 348 return shm_; |
347 } | 349 } |
348 | 350 |
349 SharedMemoryHandle SharedMemory::TakeHandle() { | 351 SharedMemoryHandle SharedMemory::TakeHandle() { |
350 SharedMemoryHandle handle(mapped_file_.Take()); | 352 SharedMemoryHandle handle(shm_); |
351 handle.SetOwnershipPassesToIPC(true); | 353 handle.SetOwnershipPassesToIPC(true); |
| 354 shm_ = SharedMemoryHandle(); |
352 memory_ = nullptr; | 355 memory_ = nullptr; |
353 mapped_size_ = 0; | 356 mapped_size_ = 0; |
354 return handle; | 357 return handle; |
355 } | 358 } |
356 | 359 |
357 } // namespace base | 360 } // namespace base |
OLD | NEW |