Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: base/shared_memory_posix.cc

Issue 7184032: Upstream android file related code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update DEPS Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/shared_memory.h" 5 #include "base/shared_memory.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <sys/mman.h> 9 #include <sys/mman.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
11 #include <unistd.h> 11 #include <unistd.h>
12 12
13 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/threading/platform_thread.h" 15 #include "base/threading/platform_thread.h"
16 #include "base/safe_strerror_posix.h" 16 #include "base/safe_strerror_posix.h"
17 #include "base/threading/thread_restrictions.h" 17 #include "base/threading/thread_restrictions.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 19
20 #if defined(OS_MACOSX) 20 #if defined(OS_MACOSX)
21 #include "base/mac/foundation_util.h" 21 #include "base/mac/foundation_util.h"
22 #endif // OS_MACOSX 22 #endif // OS_MACOSX
23 23
24 namespace base { 24 namespace base {
25 25
26 namespace { 26 namespace {
27
27 // Paranoia. Semaphores and shared memory segments should live in different 28 // Paranoia. Semaphores and shared memory segments should live in different
28 // namespaces, but who knows what's out there. 29 // namespaces, but who knows what's out there.
29 const char kSemaphoreSuffix[] = "-sem"; 30 const char kSemaphoreSuffix[] = "-sem";
31
32 #if defined(OS_ANDROID)
33 // The lockf() function is not available on Android; we translate to flock().
34 #define F_LOCK LOCK_EX
35 #define F_ULOCK LOCK_UN
36 inline int lockf(int fd, int cmd, off_t ignored_len) {
37 return flock(fd, cmd);
30 } 38 }
39 #endif
40
41 } // namespace.
31 42
32 SharedMemory::SharedMemory() 43 SharedMemory::SharedMemory()
33 : mapped_file_(-1), 44 : mapped_file_(-1),
34 mapped_size_(0), 45 mapped_size_(0),
35 inode_(0), 46 inode_(0),
36 memory_(NULL), 47 memory_(NULL),
37 read_only_(false), 48 read_only_(false),
38 created_size_(0) { 49 created_size_(0) {
39 } 50 }
40 51
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 } 99 }
89 100
90 bool SharedMemory::CreateAndMapAnonymous(uint32 size) { 101 bool SharedMemory::CreateAndMapAnonymous(uint32 size) {
91 return CreateAnonymous(size) && Map(size); 102 return CreateAnonymous(size) && Map(size);
92 } 103 }
93 104
94 bool SharedMemory::CreateAnonymous(uint32 size) { 105 bool SharedMemory::CreateAnonymous(uint32 size) {
95 return CreateNamed("", false, size); 106 return CreateNamed("", false, size);
96 } 107 }
97 108
109 #if !defined(OS_ANDROID)
98 // Chromium mostly only uses the unique/private shmem as specified by 110 // Chromium mostly only uses the unique/private shmem as specified by
99 // "name == L"". The exception is in the StatsTable. 111 // "name == L"". The exception is in the StatsTable.
100 // TODO(jrg): there is no way to "clean up" all unused named shmem if 112 // TODO(jrg): there is no way to "clean up" all unused named shmem if
101 // we restart from a crash. (That isn't a new problem, but it is a problem.) 113 // we restart from a crash. (That isn't a new problem, but it is a problem.)
102 // In case we want to delete it later, it may be useful to save the value 114 // In case we want to delete it later, it may be useful to save the value
103 // of mem_filename after FilePathForMemoryName(). 115 // of mem_filename after FilePathForMemoryName().
104 bool SharedMemory::CreateNamed(const std::string& name, 116 bool SharedMemory::CreateNamed(const std::string& name,
105 bool open_existing, uint32 size) { 117 bool open_existing, uint32 size) {
106 DCHECK_EQ(-1, mapped_file_); 118 DCHECK_EQ(-1, mapped_file_);
107 if (size == 0) return false; 119 if (size == 0) return false;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 return false; 182 return false;
171 } 183 }
172 184
173 return PrepareMapFile(fp); 185 return PrepareMapFile(fp);
174 } 186 }
175 187
176 // Our current implementation of shmem is with mmap()ing of files. 188 // Our current implementation of shmem is with mmap()ing of files.
177 // These files need to be deleted explicitly. 189 // These files need to be deleted explicitly.
178 // In practice this call is only needed for unit tests. 190 // In practice this call is only needed for unit tests.
179 bool SharedMemory::Delete(const std::string& name) { 191 bool SharedMemory::Delete(const std::string& name) {
192
joth 2011/06/19 12:48:05 nit: remove \n
michaelbai 2011/06/20 22:50:36 Done.
180 FilePath path; 193 FilePath path;
181 if (!FilePathForMemoryName(name, &path)) 194 if (!FilePathForMemoryName(name, &path))
182 return false; 195 return false;
183 196
184 if (file_util::PathExists(path)) { 197 if (file_util::PathExists(path)) {
185 return file_util::Delete(path, false); 198 return file_util::Delete(path, false);
186 } 199 }
187 200
188 // Doesn't exist, so success. 201 // Doesn't exist, so success.
189 return true; 202 return true;
190 } 203 }
191 204
192 bool SharedMemory::Open(const std::string& name, bool read_only) { 205 bool SharedMemory::Open(const std::string& name, bool read_only) {
193 FilePath path; 206 FilePath path;
194 if (!FilePathForMemoryName(name, &path)) 207 if (!FilePathForMemoryName(name, &path))
195 return false; 208 return false;
196 209
197 read_only_ = read_only; 210 read_only_ = read_only;
198 211
199 const char *mode = read_only ? "r" : "r+"; 212 const char *mode = read_only ? "r" : "r+";
200 FILE *fp = file_util::OpenFile(path, mode); 213 FILE *fp = file_util::OpenFile(path, mode);
201 return PrepareMapFile(fp); 214 return PrepareMapFile(fp);
202 } 215 }
203 216
217 #endif // !defined(OS_ANDROID)
218
204 bool SharedMemory::Map(uint32 bytes) { 219 bool SharedMemory::Map(uint32 bytes) {
205 if (mapped_file_ == -1) 220 if (mapped_file_ == -1)
206 return false; 221 return false;
207 222
223 #if defined(OS_ANDROID)
224 int ashmem_bytes = GetAshmenSizeRegion();
225 DCHECK_GE((uint32)ashmem_bytes, bytes);
joth 2011/06/19 12:48:05 nit: static_cast<uint32>(ashmem_bytes) although th
michaelbai 2011/06/20 22:50:36 Done.
226 if (bytes == 0) {
227 // The caller wants to determine the map region size from ashmem.
228 bytes = ashmem_bytes;
229 // TODO(port): we set the created size here so that it is available in
230 // transport_dib_android.cc. We should use
231 // SharedMemory::GetAshmenSizeRegion() in TransportDIB::Map().
232 created_size_ = bytes;
233 }
234 #endif
joth 2011/06/19 12:48:05 seems unfortunate to commit this hack when the cod
235
208 memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE), 236 memory_ = mmap(NULL, bytes, PROT_READ | (read_only_ ? 0 : PROT_WRITE),
209 MAP_SHARED, mapped_file_, 0); 237 MAP_SHARED, mapped_file_, 0);
210 238
211 if (memory_) 239 if (memory_)
212 mapped_size_ = bytes; 240 mapped_size_ = bytes;
213 241
214 bool mmap_succeeded = (memory_ != (void*)-1); 242 bool mmap_succeeded = (memory_ != (void*)-1);
215 DCHECK(mmap_succeeded) << "Call to mmap failed, errno=" << errno; 243 DCHECK(mmap_succeeded) << "Call to mmap failed, errno=" << errno;
216 return mmap_succeeded; 244 return mmap_succeeded;
217 } 245 }
(...skipping 23 matching lines...) Expand all
241 } 269 }
242 270
243 void SharedMemory::Lock() { 271 void SharedMemory::Lock() {
244 LockOrUnlockCommon(F_LOCK); 272 LockOrUnlockCommon(F_LOCK);
245 } 273 }
246 274
247 void SharedMemory::Unlock() { 275 void SharedMemory::Unlock() {
248 LockOrUnlockCommon(F_ULOCK); 276 LockOrUnlockCommon(F_ULOCK);
249 } 277 }
250 278
279 #if !defined(OS_ANDROID)
251 bool SharedMemory::PrepareMapFile(FILE *fp) { 280 bool SharedMemory::PrepareMapFile(FILE *fp) {
252 DCHECK_EQ(-1, mapped_file_); 281 DCHECK_EQ(-1, mapped_file_);
253 if (fp == NULL) return false; 282 if (fp == NULL) return false;
254 283
255 // This function theoretically can block on the disk, but realistically 284 // This function theoretically can block on the disk, but realistically
256 // the temporary files we create will just go into the buffer cache 285 // the temporary files we create will just go into the buffer cache
257 // and be deleted before they ever make it out to disk. 286 // and be deleted before they ever make it out to disk.
258 base::ThreadRestrictions::ScopedAllowIO allow_io; 287 base::ThreadRestrictions::ScopedAllowIO allow_io;
259 288
260 file_util::ScopedFILE file_closer(fp); 289 file_util::ScopedFILE file_closer(fp);
261 290
262 mapped_file_ = dup(fileno(fp)); 291 mapped_file_ = dup(fileno(fp));
263 if (mapped_file_ == -1) { 292 if (mapped_file_ == -1) {
264 if (errno == EMFILE) { 293 if (errno == EMFILE) {
265 LOG(WARNING) << "Shared memory creation failed; out of file descriptors"; 294 LOG(WARNING) << "Shared memory creation failed; out of file descriptors";
266 return false; 295 return false;
267 } else { 296 } else {
268 NOTREACHED() << "Call to dup failed, errno=" << errno; 297 NOTREACHED() << "Call to dup failed, errno=" << errno;
269 } 298 }
270 } 299 }
271 300
272 struct stat st; 301 struct stat st;
273 if (fstat(mapped_file_, &st)) 302 if (fstat(mapped_file_, &st))
274 NOTREACHED(); 303 NOTREACHED();
275 inode_ = st.st_ino; 304 inode_ = st.st_ino;
276 305
277 return true; 306 return true;
278 } 307 }
308 #endif
279 309
280 // For the given shmem named |mem_name|, return a filename to mmap() 310 // For the given shmem named |mem_name|, return a filename to mmap()
281 // (and possibly create). Modifies |filename|. Return false on 311 // (and possibly create). Modifies |filename|. Return false on
282 // error, or true of we are happy. 312 // error, or true of we are happy.
283 bool SharedMemory::FilePathForMemoryName(const std::string& mem_name, 313 bool SharedMemory::FilePathForMemoryName(const std::string& mem_name,
284 FilePath* path) { 314 FilePath* path) {
285 // mem_name will be used for a filename; make sure it doesn't 315 // mem_name will be used for a filename; make sure it doesn't
286 // contain anything which will confuse us. 316 // contain anything which will confuse us.
287 DCHECK_EQ(std::string::npos, mem_name.find('/')); 317 DCHECK_EQ(std::string::npos, mem_name.find('/'));
288 DCHECK_EQ(std::string::npos, mem_name.find('\0')); 318 DCHECK_EQ(std::string::npos, mem_name.find('\0'));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 new_handle->fd = new_fd; 361 new_handle->fd = new_fd;
332 new_handle->auto_close = true; 362 new_handle->auto_close = true;
333 363
334 if (close_self) 364 if (close_self)
335 Close(); 365 Close();
336 366
337 return true; 367 return true;
338 } 368 }
339 369
340 } // namespace base 370 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698