1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/shared_memory.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSharedMemory::SharedMemory() 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : mapped_file_(NULL), 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memory_(NULL), 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_only_(false), 16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch created_size_(0), 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott lock_(NULL) { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20513209b27ff55e2841eac0e4120199c23acce758Ben MurdochSharedMemory::SharedMemory(const std::wstring& name) 21513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : mapped_file_(NULL), 22513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch memory_(NULL), 23513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch read_only_(false), 24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch created_size_(0), 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch lock_(NULL), 26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch name_(name) { 27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : mapped_file_(handle), 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memory_(NULL), 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_only_(read_only), 33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch created_size_(0), 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott lock_(NULL) { 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ProcessHandle process) 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : mapped_file_(NULL), 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memory_(NULL), 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_only_(read_only), 42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch created_size_(0), 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott lock_(NULL) { 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ::DuplicateHandle(process, handle, 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GetCurrentProcess(), &mapped_file_, 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STANDARD_RIGHTS_REQUIRED | 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS), 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FALSE, 0); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSharedMemory::~SharedMemory() { 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Close(); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (lock_ != NULL) 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandle(lock_); 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return handle != NULL; 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSharedMemoryHandle SharedMemory::NULLHandle() { 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SharedMemory::CloseHandle(const SharedMemoryHandle& handle) { 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(handle != NULL); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ::CloseHandle(handle); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SharedMemory::CreateAndMapAnonymous(uint32 size) { 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return CreateAnonymous(size) && Map(size); 75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SharedMemory::CreateAnonymous(uint32 size) { 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return CreateNamed("", false, size); 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SharedMemory::CreateNamed(const std::string& name, 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool open_existing, uint32 size) { 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!mapped_file_); 84513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (size == 0) 85513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NaCl's memory allocator requires 0mod64K alignment and size for 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // shared memory objects. To allow passing shared memory to NaCl, 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // therefore we round the size actually created to the nearest 64K unit. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To avoid client impact, we continue to retain the size as the 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // actual requested size. 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 rounded_size = (size + 0xffff) & ~0xffff; 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name_ = ASCIIToWide(name); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PAGE_READWRITE, 0, static_cast<DWORD>(rounded_size), 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name_.empty() ? NULL : name_.c_str()); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!mapped_file_) 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch created_size_ = size; 101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Check if the shared memory pre-exists. 103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (GetLastError() == ERROR_ALREADY_EXISTS) { 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // If the file already existed, set created_size_ to 0 to show that 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // we don't know the size. 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch created_size_ = 0; 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!open_existing) { 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Close(); 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool SharedMemory::Delete(const std::string& name) { 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // intentionally empty -- there is nothing for us to do on Windows. 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool SharedMemory::Open(const std::string& name, bool read_only) { 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK(!mapped_file_); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name_ = ASCIIToWide(name); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_only_ = read_only; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mapped_file_ = OpenFileMapping( 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, false, 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name_.empty() ? NULL : name_.c_str()); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (mapped_file_ != NULL) { 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Note: size_ is not set in this case. 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SharedMemory::Map(uint32 bytes) { 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (mapped_file_ == NULL) 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memory_ = MapViewOfFile(mapped_file_, 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, 0, 0, bytes); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memory_ != NULL) { 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SharedMemory::Unmap() { 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memory_ == NULL) 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott UnmapViewOfFile(memory_); 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memory_ = NULL; 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SharedMemory::ShareToProcessCommon(ProcessHandle process, 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SharedMemoryHandle *new_handle, 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool close_self) { 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *new_handle = 0; 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD options = 0; 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE mapped_file = mapped_file_; 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE result; 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!read_only_) 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott access |= FILE_MAP_WRITE; 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (close_self) { 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file. 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott options = DUPLICATE_CLOSE_SOURCE; 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mapped_file_ = NULL; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Unmap(); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (process == GetCurrentProcess() && close_self) { 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *new_handle = mapped_file; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!DuplicateHandle(GetCurrentProcess(), mapped_file, process, 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &result, access, FALSE, options)) 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *new_handle = result; 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SharedMemory::Close() { 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (memory_ != NULL) { 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott UnmapViewOfFile(memory_); 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memory_ = NULL; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (mapped_file_ != NULL) { 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandle(mapped_file_); 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mapped_file_ = NULL; 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SharedMemory::Lock() { 2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch Lock(INFINITE, NULL); 201513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 202513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 2034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool SharedMemory::Lock(uint32 timeout_ms, SECURITY_ATTRIBUTES* sec_attr) { 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (lock_ == NULL) { 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::wstring name = name_; 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott name.append(L"lock"); 2074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch lock_ = CreateMutex(sec_attr, FALSE, name.c_str()); 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (lock_ == NULL) { 2094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch PLOG(ERROR) << "Could not create mutex."; 210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; // there is nothing good we can do here. 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 213513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DWORD result = WaitForSingleObject(lock_, timeout_ms); 214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Return false for WAIT_ABANDONED, WAIT_TIMEOUT or WAIT_FAILED. 216513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return (result == WAIT_OBJECT_0); 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SharedMemory::Unlock() { 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(lock_ != NULL); 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReleaseMutex(lock_); 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSharedMemoryHandle SharedMemory::handle() const { 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return mapped_file_; 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 229