blob: f35ada1e2814dbc7f9a268651b2b6db4d3d77cec [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commitd7cae122008-07-26 21:49:384
5#include "base/shared_memory.h"
6
7#include "base/logging.h"
[email protected]b6413b49b2010-09-29 20:32:228#include "base/utf_string_conversions.h"
initial.commitd7cae122008-07-26 21:49:389
[email protected]176aa482008-11-14 03:25:1510namespace base {
11
initial.commitd7cae122008-07-26 21:49:3812SharedMemory::SharedMemory()
13 : mapped_file_(NULL),
14 memory_(NULL),
15 read_only_(false),
16 max_size_(0),
17 lock_(NULL) {
18}
19
20SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only)
21 : mapped_file_(handle),
22 memory_(NULL),
23 read_only_(read_only),
24 max_size_(0),
25 lock_(NULL) {
26}
27
28SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only,
29 ProcessHandle process)
30 : mapped_file_(NULL),
31 memory_(NULL),
32 read_only_(read_only),
33 max_size_(0),
34 lock_(NULL) {
35 ::DuplicateHandle(process, handle,
36 GetCurrentProcess(), &mapped_file_,
37 STANDARD_RIGHTS_REQUIRED |
38 (read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS),
39 FALSE, 0);
40}
41
42SharedMemory::~SharedMemory() {
43 Close();
44 if (lock_ != NULL)
45 CloseHandle(lock_);
46}
47
[email protected]5fe733de2009-02-11 18:59:2048// static
49bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
50 return handle != NULL;
51}
52
[email protected]76aac1e2009-03-16 16:45:3653// static
54SharedMemoryHandle SharedMemory::NULLHandle() {
55 return NULL;
56}
57
[email protected]b0af04c2009-05-18 17:46:3158// static
59void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
60 DCHECK(handle != NULL);
61 ::CloseHandle(handle);
62}
63
[email protected]b6413b49b2010-09-29 20:32:2264bool SharedMemory::Create(const std::string& name, bool read_only,
[email protected]b5ab3982010-02-16 23:58:2765 bool open_existing, uint32 size) {
initial.commitd7cae122008-07-26 21:49:3866 DCHECK(mapped_file_ == NULL);
67
[email protected]97684352010-03-25 15:40:2468 // NaCl's memory allocator requires 0mod64K alignment and size for
69 // shared memory objects. To allow passing shared memory to NaCl,
70 // therefore we round the size actually created to the nearest 64K unit.
71 // To avoid client impact, we continue to retain the size as the
72 // actual requested size.
73 uint32 rounded_size = (size + 0xffff) & ~0xffff;
[email protected]b6413b49b2010-09-29 20:32:2274 name_ = ASCIIToWide(name);
initial.commitd7cae122008-07-26 21:49:3875 read_only_ = read_only;
76 mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
[email protected]97684352010-03-25 15:40:2477 read_only_ ? PAGE_READONLY : PAGE_READWRITE, 0,
78 static_cast<DWORD>(rounded_size),
[email protected]b6413b49b2010-09-29 20:32:2279 name_.empty() ? NULL : name_.c_str());
initial.commitd7cae122008-07-26 21:49:3880 if (!mapped_file_)
81 return false;
82
83 // Check if the shared memory pre-exists.
84 if (GetLastError() == ERROR_ALREADY_EXISTS && !open_existing) {
85 Close();
86 return false;
87 }
88 max_size_ = size;
89 return true;
90}
91
[email protected]b6413b49b2010-09-29 20:32:2292bool SharedMemory::Delete(const std::string& name) {
[email protected]9e51af92009-02-04 00:58:3993 // intentionally empty -- there is nothing for us to do on Windows.
94 return true;
95}
96
[email protected]b6413b49b2010-09-29 20:32:2297bool SharedMemory::Open(const std::string& name, bool read_only) {
initial.commitd7cae122008-07-26 21:49:3898 DCHECK(mapped_file_ == NULL);
99
[email protected]b6413b49b2010-09-29 20:32:22100 name_ = ASCIIToWide(name);
initial.commitd7cae122008-07-26 21:49:38101 read_only_ = read_only;
102 mapped_file_ = OpenFileMapping(
103 read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, false,
[email protected]b6413b49b2010-09-29 20:32:22104 name_.empty() ? NULL : name_.c_str());
initial.commitd7cae122008-07-26 21:49:38105 if (mapped_file_ != NULL) {
106 // Note: size_ is not set in this case.
107 return true;
108 }
109 return false;
110}
111
[email protected]b5ab3982010-02-16 23:58:27112bool SharedMemory::Map(uint32 bytes) {
initial.commitd7cae122008-07-26 21:49:38113 if (mapped_file_ == NULL)
114 return false;
115
116 memory_ = MapViewOfFile(mapped_file_,
117 read_only_ ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, 0, 0, bytes);
118 if (memory_ != NULL) {
119 return true;
120 }
121 return false;
122}
123
124bool SharedMemory::Unmap() {
125 if (memory_ == NULL)
126 return false;
127
128 UnmapViewOfFile(memory_);
129 memory_ = NULL;
130 return true;
131}
132
133bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
134 SharedMemoryHandle *new_handle,
135 bool close_self) {
136 *new_handle = 0;
137 DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ;
138 DWORD options = 0;
139 HANDLE mapped_file = mapped_file_;
140 HANDLE result;
141 if (!read_only_)
142 access |= FILE_MAP_WRITE;
143 if (close_self) {
144 // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file.
145 options = DUPLICATE_CLOSE_SOURCE;
146 mapped_file_ = NULL;
147 Unmap();
148 }
149
150 if (process == GetCurrentProcess() && close_self) {
151 *new_handle = mapped_file;
152 return true;
153 }
154
155 if (!DuplicateHandle(GetCurrentProcess(), mapped_file, process,
156 &result, access, FALSE, options))
157 return false;
158 *new_handle = result;
159 return true;
160}
161
162
163void SharedMemory::Close() {
164 if (memory_ != NULL) {
165 UnmapViewOfFile(memory_);
166 memory_ = NULL;
167 }
168
169 if (mapped_file_ != NULL) {
170 CloseHandle(mapped_file_);
171 mapped_file_ = NULL;
172 }
173}
174
175void SharedMemory::Lock() {
176 if (lock_ == NULL) {
177 std::wstring name = name_;
178 name.append(L"lock");
179 lock_ = CreateMutex(NULL, FALSE, name.c_str());
180 DCHECK(lock_ != NULL);
181 if (lock_ == NULL) {
182 DLOG(ERROR) << "Could not create mutex" << GetLastError();
183 return; // there is nothing good we can do here.
184 }
185 }
186 WaitForSingleObject(lock_, INFINITE);
187}
188
189void SharedMemory::Unlock() {
190 DCHECK(lock_ != NULL);
191 ReleaseMutex(lock_);
192}
license.botbf09a502008-08-24 00:55:55193
[email protected]5fe733de2009-02-11 18:59:20194SharedMemoryHandle SharedMemory::handle() const {
195 return mapped_file_;
196}
197
[email protected]176aa482008-11-14 03:25:15198} // namespace base