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

Side by Side Diff: base/memory/shared_memory_posix.cc

Issue 197873014: Revert of Implement ScopedFD in terms of ScopedGeneric. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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
« no previous file with comments | « base/memory/shared_memory.h ('k') | base/posix/unix_domain_socket_linux_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <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>
(...skipping 12 matching lines...) Expand all
23 23
24 #if defined(OS_MACOSX) 24 #if defined(OS_MACOSX)
25 #include "base/mac/foundation_util.h" 25 #include "base/mac/foundation_util.h"
26 #endif // OS_MACOSX 26 #endif // OS_MACOSX
27 27
28 #if defined(OS_ANDROID) 28 #if defined(OS_ANDROID)
29 #include "base/os_compat_android.h" 29 #include "base/os_compat_android.h"
30 #include "third_party/ashmem/ashmem.h" 30 #include "third_party/ashmem/ashmem.h"
31 #endif 31 #endif
32 32
33 using file_util::ScopedFD;
33 using file_util::ScopedFILE; 34 using file_util::ScopedFILE;
34 35
35 namespace base { 36 namespace base {
36 37
37 namespace { 38 namespace {
38 39
39 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER; 40 LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER;
40 41
41 } 42 }
42 43
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 if (options.size > static_cast<size_t>(std::numeric_limits<int>::max())) 125 if (options.size > static_cast<size_t>(std::numeric_limits<int>::max()))
125 return false; 126 return false;
126 127
127 // This function theoretically can block on the disk, but realistically 128 // This function theoretically can block on the disk, but realistically
128 // the temporary files we create will just go into the buffer cache 129 // the temporary files we create will just go into the buffer cache
129 // and be deleted before they ever make it out to disk. 130 // and be deleted before they ever make it out to disk.
130 base::ThreadRestrictions::ScopedAllowIO allow_io; 131 base::ThreadRestrictions::ScopedAllowIO allow_io;
131 132
132 ScopedFILE fp; 133 ScopedFILE fp;
133 bool fix_size = true; 134 bool fix_size = true;
134 ScopedFD readonly_fd; 135 int readonly_fd_storage = -1;
136 ScopedFD readonly_fd(&readonly_fd_storage);
135 137
136 FilePath path; 138 FilePath path;
137 if (options.name_deprecated == NULL || options.name_deprecated->empty()) { 139 if (options.name_deprecated == NULL || options.name_deprecated->empty()) {
138 // It doesn't make sense to have a open-existing private piece of shmem 140 // It doesn't make sense to have a open-existing private piece of shmem
139 DCHECK(!options.open_existing_deprecated); 141 DCHECK(!options.open_existing_deprecated);
140 // Q: Why not use the shm_open() etc. APIs? 142 // Q: Why not use the shm_open() etc. APIs?
141 // A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU 143 // A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU
142 fp.reset(base::CreateAndOpenTemporaryShmemFile(&path, options.executable)); 144 fp.reset(base::CreateAndOpenTemporaryShmemFile(&path, options.executable));
143 145
144 if (fp) { 146 if (fp) {
145 // Also open as readonly so that we can ShareReadOnlyToProcess. 147 // Also open as readonly so that we can ShareReadOnlyToProcess.
146 readonly_fd.reset(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); 148 *readonly_fd = HANDLE_EINTR(open(path.value().c_str(), O_RDONLY));
147 if (!readonly_fd.is_valid()) { 149 if (*readonly_fd < 0) {
148 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed"; 150 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
149 fp.reset(); 151 fp.reset();
150 } 152 }
151 // Deleting the file prevents anyone else from mapping it in (making it 153 // Deleting the file prevents anyone else from mapping it in (making it
152 // private), and prevents the need for cleanup (once the last fd is 154 // private), and prevents the need for cleanup (once the last fd is
153 // closed, it is truly freed). 155 // closed, it is truly freed).
154 if (unlink(path.value().c_str())) 156 if (unlink(path.value().c_str()))
155 PLOG(WARNING) << "unlink"; 157 PLOG(WARNING) << "unlink";
156 } 158 }
157 } else { 159 } else {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 "Invalid owner when opening existing shared memory file."; 191 "Invalid owner when opening existing shared memory file.";
190 close(fd); 192 close(fd);
191 return false; 193 return false;
192 } 194 }
193 195
194 // An existing file was opened, so its size should not be fixed. 196 // An existing file was opened, so its size should not be fixed.
195 fix_size = false; 197 fix_size = false;
196 } 198 }
197 199
198 // Also open as readonly so that we can ShareReadOnlyToProcess. 200 // Also open as readonly so that we can ShareReadOnlyToProcess.
199 readonly_fd.reset(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); 201 *readonly_fd = HANDLE_EINTR(open(path.value().c_str(), O_RDONLY));
200 if (!readonly_fd.is_valid()) { 202 if (*readonly_fd < 0) {
201 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed"; 203 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
202 close(fd); 204 close(fd);
203 fd = -1; 205 fd = -1;
204 } 206 }
205 if (fd >= 0) { 207 if (fd >= 0) {
206 // "a+" is always appropriate: if it's a new file, a+ is similar to w+. 208 // "a+" is always appropriate: if it's a new file, a+ is similar to w+.
207 fp.reset(fdopen(fd, "a+")); 209 fp.reset(fdopen(fd, "a+"));
208 } 210 }
209 } 211 }
210 if (fp && fix_size) { 212 if (fp && fix_size) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 258
257 bool SharedMemory::Open(const std::string& name, bool read_only) { 259 bool SharedMemory::Open(const std::string& name, bool read_only) {
258 FilePath path; 260 FilePath path;
259 if (!FilePathForMemoryName(name, &path)) 261 if (!FilePathForMemoryName(name, &path))
260 return false; 262 return false;
261 263
262 read_only_ = read_only; 264 read_only_ = read_only;
263 265
264 const char *mode = read_only ? "r" : "r+"; 266 const char *mode = read_only ? "r" : "r+";
265 ScopedFILE fp(base::OpenFile(path, mode)); 267 ScopedFILE fp(base::OpenFile(path, mode));
266 ScopedFD readonly_fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); 268 int readonly_fd_storage = -1;
267 if (!readonly_fd.is_valid()) { 269 ScopedFD readonly_fd(&readonly_fd_storage);
270 *readonly_fd = HANDLE_EINTR(open(path.value().c_str(), O_RDONLY));
271 if (*readonly_fd < 0) {
268 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed"; 272 DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
269 } 273 }
270 return PrepareMapFile(fp.Pass(), readonly_fd.Pass()); 274 return PrepareMapFile(fp.Pass(), readonly_fd.Pass());
271 } 275 }
272 276
273 #endif // !defined(OS_ANDROID) 277 #endif // !defined(OS_ANDROID)
274 278
275 bool SharedMemory::MapAt(off_t offset, size_t bytes) { 279 bool SharedMemory::MapAt(off_t offset, size_t bytes) {
276 if (mapped_file_ == -1) 280 if (mapped_file_ == -1)
277 return false; 281 return false;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 346
343 void SharedMemory::UnlockDeprecated() { 347 void SharedMemory::UnlockDeprecated() {
344 LockOrUnlockCommon(F_ULOCK); 348 LockOrUnlockCommon(F_ULOCK);
345 g_thread_lock_.Get().Release(); 349 g_thread_lock_.Get().Release();
346 } 350 }
347 351
348 #if !defined(OS_ANDROID) 352 #if !defined(OS_ANDROID)
349 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) { 353 bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) {
350 DCHECK_EQ(-1, mapped_file_); 354 DCHECK_EQ(-1, mapped_file_);
351 DCHECK_EQ(-1, readonly_mapped_file_); 355 DCHECK_EQ(-1, readonly_mapped_file_);
352 if (fp == NULL || !readonly_fd.is_valid()) return false; 356 if (fp == NULL || *readonly_fd < 0) return false;
353 357
354 // This function theoretically can block on the disk, but realistically 358 // This function theoretically can block on the disk, but realistically
355 // the temporary files we create will just go into the buffer cache 359 // the temporary files we create will just go into the buffer cache
356 // and be deleted before they ever make it out to disk. 360 // and be deleted before they ever make it out to disk.
357 base::ThreadRestrictions::ScopedAllowIO allow_io; 361 base::ThreadRestrictions::ScopedAllowIO allow_io;
358 362
359 struct stat st = {}; 363 struct stat st = {};
360 struct stat readonly_st = {}; 364 struct stat readonly_st = {};
361 if (fstat(fileno(fp.get()), &st)) 365 if (fstat(fileno(fp.get()), &st))
362 NOTREACHED(); 366 NOTREACHED();
363 if (fstat(readonly_fd.get(), &readonly_st)) 367 if (fstat(*readonly_fd, &readonly_st))
364 NOTREACHED(); 368 NOTREACHED();
365 if (st.st_dev != readonly_st.st_dev || st.st_ino != readonly_st.st_ino) { 369 if (st.st_dev != readonly_st.st_dev || st.st_ino != readonly_st.st_ino) {
366 LOG(ERROR) << "writable and read-only inodes don't match; bailing"; 370 LOG(ERROR) << "writable and read-only inodes don't match; bailing";
367 return false; 371 return false;
368 } 372 }
369 373
370 mapped_file_ = dup(fileno(fp.get())); 374 mapped_file_ = dup(fileno(fp.get()));
371 if (mapped_file_ == -1) { 375 if (mapped_file_ == -1) {
372 if (errno == EMFILE) { 376 if (errno == EMFILE) {
373 LOG(WARNING) << "Shared memory creation failed; out of file descriptors"; 377 LOG(WARNING) << "Shared memory creation failed; out of file descriptors";
374 return false; 378 return false;
375 } else { 379 } else {
376 NOTREACHED() << "Call to dup failed, errno=" << errno; 380 NOTREACHED() << "Call to dup failed, errno=" << errno;
377 } 381 }
378 } 382 }
379 inode_ = st.st_ino; 383 inode_ = st.st_ino;
380 readonly_mapped_file_ = readonly_fd.release(); 384 readonly_mapped_file_ = *readonly_fd.release();
381 385
382 return true; 386 return true;
383 } 387 }
384 #endif 388 #endif
385 389
386 // For the given shmem named |mem_name|, return a filename to mmap() 390 // For the given shmem named |mem_name|, return a filename to mmap()
387 // (and possibly create). Modifies |filename|. Return false on 391 // (and possibly create). Modifies |filename|. Return false on
388 // error, or true of we are happy. 392 // error, or true of we are happy.
389 bool SharedMemory::FilePathForMemoryName(const std::string& mem_name, 393 bool SharedMemory::FilePathForMemoryName(const std::string& mem_name,
390 FilePath* path) { 394 FilePath* path) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 new_handle->fd = new_fd; 459 new_handle->fd = new_fd;
456 new_handle->auto_close = true; 460 new_handle->auto_close = true;
457 461
458 if (close_self) 462 if (close_self)
459 Close(); 463 Close();
460 464
461 return true; 465 return true;
462 } 466 }
463 467
464 } // namespace base 468 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/shared_memory.h ('k') | base/posix/unix_domain_socket_linux_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698