1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/shared_memory_win.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,186 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/shared_memory.h" 1.9 + 1.10 +#include "base/logging.h" 1.11 +#include "base/win_util.h" 1.12 +#include "base/string_util.h" 1.13 + 1.14 +namespace base { 1.15 + 1.16 +SharedMemory::SharedMemory() 1.17 + : mapped_file_(NULL), 1.18 + memory_(NULL), 1.19 + read_only_(false), 1.20 + max_size_(0), 1.21 + lock_(NULL) { 1.22 +} 1.23 + 1.24 +SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only) 1.25 + : mapped_file_(handle), 1.26 + memory_(NULL), 1.27 + read_only_(read_only), 1.28 + max_size_(0), 1.29 + lock_(NULL) { 1.30 +} 1.31 + 1.32 +SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only, 1.33 + ProcessHandle process) 1.34 + : mapped_file_(NULL), 1.35 + memory_(NULL), 1.36 + read_only_(read_only), 1.37 + max_size_(0), 1.38 + lock_(NULL) { 1.39 + ::DuplicateHandle(process, handle, 1.40 + GetCurrentProcess(), &mapped_file_, 1.41 + STANDARD_RIGHTS_REQUIRED | 1.42 + (read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS), 1.43 + FALSE, 0); 1.44 +} 1.45 + 1.46 +SharedMemory::~SharedMemory() { 1.47 + Close(); 1.48 + if (lock_ != NULL) 1.49 + CloseHandle(lock_); 1.50 +} 1.51 + 1.52 +// static 1.53 +bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) { 1.54 + return handle != NULL; 1.55 +} 1.56 + 1.57 +// static 1.58 +SharedMemoryHandle SharedMemory::NULLHandle() { 1.59 + return NULL; 1.60 +} 1.61 + 1.62 +bool SharedMemory::Create(const std::string &cname, bool read_only, 1.63 + bool open_existing, size_t size) { 1.64 + DCHECK(mapped_file_ == NULL); 1.65 + std::wstring name = UTF8ToWide(cname); 1.66 + name_ = name; 1.67 + read_only_ = read_only; 1.68 + mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, 1.69 + read_only_ ? PAGE_READONLY : PAGE_READWRITE, 0, static_cast<DWORD>(size), 1.70 + name.empty() ? NULL : name.c_str()); 1.71 + if (!mapped_file_) 1.72 + return false; 1.73 + 1.74 + // Check if the shared memory pre-exists. 1.75 + if (GetLastError() == ERROR_ALREADY_EXISTS && !open_existing) { 1.76 + Close(); 1.77 + return false; 1.78 + } 1.79 + max_size_ = size; 1.80 + return true; 1.81 +} 1.82 + 1.83 +bool SharedMemory::Delete(const std::wstring& name) { 1.84 + // intentionally empty -- there is nothing for us to do on Windows. 1.85 + return true; 1.86 +} 1.87 + 1.88 +bool SharedMemory::Open(const std::wstring &name, bool read_only) { 1.89 + DCHECK(mapped_file_ == NULL); 1.90 + 1.91 + name_ = name; 1.92 + read_only_ = read_only; 1.93 + mapped_file_ = OpenFileMapping( 1.94 + read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, false, 1.95 + name.empty() ? NULL : name.c_str()); 1.96 + if (mapped_file_ != NULL) { 1.97 + // Note: size_ is not set in this case. 1.98 + return true; 1.99 + } 1.100 + return false; 1.101 +} 1.102 + 1.103 +bool SharedMemory::Map(size_t bytes) { 1.104 + if (mapped_file_ == NULL) 1.105 + return false; 1.106 + 1.107 + memory_ = MapViewOfFile(mapped_file_, 1.108 + read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, 0, 0, bytes); 1.109 + if (memory_ != NULL) { 1.110 + return true; 1.111 + } 1.112 + return false; 1.113 +} 1.114 + 1.115 +bool SharedMemory::Unmap() { 1.116 + if (memory_ == NULL) 1.117 + return false; 1.118 + 1.119 + UnmapViewOfFile(memory_); 1.120 + memory_ = NULL; 1.121 + return true; 1.122 +} 1.123 + 1.124 +bool SharedMemory::ShareToProcessCommon(ProcessHandle process, 1.125 + SharedMemoryHandle *new_handle, 1.126 + bool close_self) { 1.127 + *new_handle = 0; 1.128 + DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ; 1.129 + DWORD options = 0; 1.130 + HANDLE mapped_file = mapped_file_; 1.131 + HANDLE result; 1.132 + if (!read_only_) 1.133 + access |= FILE_MAP_WRITE; 1.134 + if (close_self) { 1.135 + // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file. 1.136 + options = DUPLICATE_CLOSE_SOURCE; 1.137 + mapped_file_ = NULL; 1.138 + Unmap(); 1.139 + } 1.140 + 1.141 + if (process == GetCurrentProcess() && close_self) { 1.142 + *new_handle = mapped_file; 1.143 + return true; 1.144 + } 1.145 + 1.146 + if (!DuplicateHandle(GetCurrentProcess(), mapped_file, process, 1.147 + &result, access, FALSE, options)) 1.148 + return false; 1.149 + *new_handle = result; 1.150 + return true; 1.151 +} 1.152 + 1.153 + 1.154 +void SharedMemory::Close() { 1.155 + if (memory_ != NULL) { 1.156 + UnmapViewOfFile(memory_); 1.157 + memory_ = NULL; 1.158 + } 1.159 + 1.160 + if (mapped_file_ != NULL) { 1.161 + CloseHandle(mapped_file_); 1.162 + mapped_file_ = NULL; 1.163 + } 1.164 +} 1.165 + 1.166 +void SharedMemory::Lock() { 1.167 + if (lock_ == NULL) { 1.168 + std::wstring name = name_; 1.169 + name.append(L"lock"); 1.170 + lock_ = CreateMutex(NULL, FALSE, name.c_str()); 1.171 + DCHECK(lock_ != NULL); 1.172 + if (lock_ == NULL) { 1.173 + DLOG(ERROR) << "Could not create mutex" << GetLastError(); 1.174 + return; // there is nothing good we can do here. 1.175 + } 1.176 + } 1.177 + WaitForSingleObject(lock_, INFINITE); 1.178 +} 1.179 + 1.180 +void SharedMemory::Unlock() { 1.181 + DCHECK(lock_ != NULL); 1.182 + ReleaseMutex(lock_); 1.183 +} 1.184 + 1.185 +SharedMemoryHandle SharedMemory::handle() const { 1.186 + return mapped_file_; 1.187 +} 1.188 + 1.189 +} // namespace base