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

Unified Diff: base/memory/shared_memory_posix.cc

Issue 1180693002: Update from https://crrev.com/333737 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/memory/shared_memory_nacl.cc ('k') | base/memory/shared_memory_win.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/memory/shared_memory_posix.cc
diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
index d6c290fa01617581afbaac2a442f7cadc92464a0..35d746e5394e0e042bbaac33421d94c8406e65e2 100644
--- a/base/memory/shared_memory_posix.cc
+++ b/base/memory/shared_memory_posix.cc
@@ -15,9 +15,11 @@
#include "base/files/scoped_file.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/posix/safe_strerror.h"
#include "base/process/process_metrics.h"
#include "base/profiler/scoped_tracker.h"
-#include "base/safe_strerror_posix.h"
+#include "base/scoped_generic.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
@@ -38,12 +40,78 @@ namespace {
LazyInstance<Lock>::Leaky g_thread_lock_ = LAZY_INSTANCE_INITIALIZER;
+struct ScopedPathUnlinkerTraits {
+ static FilePath* InvalidValue() { return nullptr; }
+
+ static void Free(FilePath* path) {
+ // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437
+ // is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "466437 SharedMemory::Create::Unlink"));
+ if (unlink(path->value().c_str()))
+ PLOG(WARNING) << "unlink";
+ }
+};
+
+// Unlinks the FilePath when the object is destroyed.
+typedef ScopedGeneric<FilePath*, ScopedPathUnlinkerTraits> ScopedPathUnlinker;
+
+#if !defined(OS_ANDROID)
+// Makes a temporary file, fdopens it, and then unlinks it. |fp| is populated
+// with the fdopened FILE. |readonly_fd| is populated with the opened fd if
+// options.share_read_only is true. |path| is populated with the location of
+// the file before it was unlinked.
+// Returns false if there's an unhandled failure.
+bool CreateAnonymousSharedMemory(const SharedMemoryCreateOptions& options,
+ ScopedFILE* fp,
+ ScopedFD* readonly_fd,
+ FilePath* path) {
+ // It doesn't make sense to have a open-existing private piece of shmem
+ DCHECK(!options.open_existing_deprecated);
+ // Q: Why not use the shm_open() etc. APIs?
+ // A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU
+ FilePath directory;
+ ScopedPathUnlinker path_unlinker;
+ if (GetShmemTempDir(options.executable, &directory)) {
+ // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437
+ // is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "466437 SharedMemory::Create::OpenTemporaryFile"));
+ fp->reset(base::CreateAndOpenTemporaryFileInDir(directory, path));
+
+ // Deleting the file prevents anyone else from mapping it in (making it
+ // private), and prevents the need for cleanup (once the last fd is
+ // closed, it is truly freed).
+ if (*fp)
+ path_unlinker.reset(path);
+ }
+
+ if (*fp) {
+ if (options.share_read_only) {
+ // TODO(erikchen): Remove ScopedTracker below once
+ // http://crbug.com/466437 is fixed.
+ tracked_objects::ScopedTracker tracking_profile(
+ FROM_HERE_WITH_EXPLICIT_FUNCTION(
+ "466437 SharedMemory::Create::OpenReadonly"));
+ // Also open as readonly so that we can ShareReadOnlyToProcess.
+ readonly_fd->reset(HANDLE_EINTR(open(path->value().c_str(), O_RDONLY)));
+ if (!readonly_fd->is_valid()) {
+ DPLOG(ERROR) << "open(\"" << path->value() << "\", O_RDONLY) failed";
+ fp->reset();
+ return false;
+ }
+ }
+ }
+ return true;
+}
+#endif // !defined(OS_ANDROID)
}
SharedMemory::SharedMemory()
: mapped_file_(-1),
readonly_mapped_file_(-1),
- inode_(0),
mapped_size_(0),
memory_(NULL),
read_only_(false),
@@ -53,24 +121,16 @@ SharedMemory::SharedMemory()
SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only)
: mapped_file_(handle.fd),
readonly_mapped_file_(-1),
- inode_(0),
mapped_size_(0),
memory_(NULL),
read_only_(read_only),
requested_size_(0) {
- struct stat st;
- if (fstat(handle.fd, &st) == 0) {
- // If fstat fails, then the file descriptor is invalid and we'll learn this
- // fact when Map() fails.
- inode_ = st.st_ino;
- }
}
SharedMemory::SharedMemory(SharedMemoryHandle handle, bool read_only,
ProcessHandle process)
: mapped_file_(handle.fd),
readonly_mapped_file_(-1),
- inode_(0),
mapped_size_(0),
memory_(NULL),
read_only_(read_only),
@@ -107,11 +167,35 @@ size_t SharedMemory::GetHandleLimit() {
return base::GetMaxFds();
}
+// static
+SharedMemoryHandle SharedMemory::DuplicateHandle(
+ const SharedMemoryHandle& handle) {
+ int duped_handle = HANDLE_EINTR(dup(handle.fd));
+ if (duped_handle < 0)
+ return base::SharedMemory::NULLHandle();
+ return base::FileDescriptor(duped_handle, true);
+}
+
+// static
+int SharedMemory::GetFdFromSharedMemoryHandle(
+ const SharedMemoryHandle& handle) {
+ return handle.fd;
+}
+
bool SharedMemory::CreateAndMapAnonymous(size_t size) {
return CreateAnonymous(size) && Map(size);
}
#if !defined(OS_ANDROID)
+// static
+int SharedMemory::GetSizeFromSharedMemoryHandle(
+ const SharedMemoryHandle& handle) {
+ struct stat st;
+ if (fstat(handle.fd, &st) != 0)
+ return -1;
+ return st.st_size;
+}
+
// Chromium mostly only uses the unique/private shmem as specified by
// "name == L"". The exception is in the StatsTable.
// TODO(jrg): there is no way to "clean up" all unused named shmem if
@@ -141,47 +225,10 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
FilePath path;
if (options.name_deprecated == NULL || options.name_deprecated->empty()) {
- // It doesn't make sense to have a open-existing private piece of shmem
- DCHECK(!options.open_existing_deprecated);
- // Q: Why not use the shm_open() etc. APIs?
- // A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU
- FilePath directory;
- if (GetShmemTempDir(options.executable, &directory)) {
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile2(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "466437 SharedMemory::Create::OpenTemporaryFile"));
- fp.reset(CreateAndOpenTemporaryFileInDir(directory, &path));
- }
-
- if (fp) {
- if (options.share_read_only) {
- // TODO(erikchen): Remove ScopedTracker below once
- // http://crbug.com/466437 is fixed.
- tracked_objects::ScopedTracker tracking_profile3(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "466437 SharedMemory::Create::OpenReadonly"));
- // Also open as readonly so that we can ShareReadOnlyToProcess.
- readonly_fd.reset(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY)));
- if (!readonly_fd.is_valid()) {
- DPLOG(ERROR) << "open(\"" << path.value() << "\", O_RDONLY) failed";
- fp.reset();
- return false;
- }
- }
-
- // TODO(erikchen): Remove ScopedTracker below once http://crbug.com/466437
- // is fixed.
- tracked_objects::ScopedTracker tracking_profile4(
- FROM_HERE_WITH_EXPLICIT_FUNCTION(
- "466437 SharedMemory::Create::Unlink"));
- // Deleting the file prevents anyone else from mapping it in (making it
- // private), and prevents the need for cleanup (once the last fd is
- // closed, it is truly freed).
- if (unlink(path.value().c_str()))
- PLOG(WARNING) << "unlink";
- }
+ bool result =
+ CreateAnonymousSharedMemory(options, &fp, &readonly_fd, &path);
+ if (!result)
+ return false;
} else {
if (!FilePathForMemoryName(*options.name_deprecated, &path))
return false;
@@ -402,7 +449,7 @@ bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) {
}
}
- mapped_file_ = dup(fileno(fp.get()));
+ mapped_file_ = HANDLE_EINTR(dup(fileno(fp.get())));
if (mapped_file_ == -1) {
if (errno == EMFILE) {
LOG(WARNING) << "Shared memory creation failed; out of file descriptors";
@@ -411,7 +458,6 @@ bool SharedMemory::PrepareMapFile(ScopedFILE fp, ScopedFD readonly_fd) {
NOTREACHED() << "Call to dup failed, errno=" << errno;
}
}
- inode_ = st.st_ino;
readonly_mapped_file_ = readonly_fd.release();
return true;
@@ -459,7 +505,7 @@ void SharedMemory::LockOrUnlockCommon(int function) {
<< " function:" << function
<< " fd:" << mapped_file_
<< " errno:" << errno
- << " msg:" << safe_strerror(errno);
+ << " msg:" << base::safe_strerror(errno);
}
}
}
@@ -481,7 +527,7 @@ bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
break;
}
- const int new_fd = dup(handle_to_dup);
+ const int new_fd = HANDLE_EINTR(dup(handle_to_dup));
if (new_fd < 0) {
DPLOG(ERROR) << "dup() failed.";
return false;
« no previous file with comments | « base/memory/shared_memory_nacl.cc ('k') | base/memory/shared_memory_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698