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

Unified Diff: base/metrics/field_trial.cc

Issue 2862123002: Pass the GUID for the SharedMemoryHandle used by base::FieldTrialList. (Closed)
Patch Set: Pass string piece by value. Created 3 years, 7 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/metrics/field_trial.h ('k') | base/metrics/field_trial_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/field_trial.cc
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
index 78602f1e613d39f00020dea6f1f18f093bcfa72f..5711aec2373483c3944192d108cf04e9a15eafb9 100644
--- a/base/metrics/field_trial.cc
+++ b/base/metrics/field_trial.cc
@@ -16,6 +16,7 @@
#include "base/process/memory.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -208,25 +209,6 @@ void AddFeatureAndFieldTrialFlags(const char* enable_features_switch,
}
}
-#if defined(OS_WIN)
-HANDLE CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) {
- HANDLE src = allocator->shared_memory()->handle().GetHandle();
- ProcessHandle process = GetCurrentProcess();
- DWORD access = SECTION_MAP_READ | SECTION_QUERY;
- HANDLE dst;
- if (!::DuplicateHandle(process, src, process, &dst, access, true, 0))
- return kInvalidPlatformFile;
- return dst;
-}
-#endif
-
-#if defined(OS_POSIX) && !defined(OS_NACL)
-int CreateReadOnlyHandle(FieldTrialList::FieldTrialAllocator* allocator) {
- SharedMemoryHandle handle = allocator->shared_memory()->GetReadOnlyHandle();
- return SharedMemory::GetFdFromSharedMemoryHandle(handle);
-}
-#endif
-
void OnOutOfMemory(size_t size) {
#if defined(OS_NACL)
NOTREACHED();
@@ -235,6 +217,23 @@ void OnOutOfMemory(size_t size) {
#endif
}
+#if !defined(OS_NACL)
+// Returns whether the operation succeeded.
+bool DeserializeGUIDFromStringPieces(base::StringPiece first,
+ base::StringPiece second,
+ base::UnguessableToken* guid) {
+ uint64_t high = 0;
+ uint64_t low = 0;
+ if (!base::StringToUint64(first, &high) ||
+ !base::StringToUint64(second, &low)) {
+ return false;
+ }
+
+ *guid = base::UnguessableToken::Deserialize(high, low);
+ return true;
+}
+#endif
+
} // namespace
// statics
@@ -781,9 +780,9 @@ void FieldTrialList::CreateTrialsFromCommandLine(
#if defined(OS_WIN)
if (cmd_line.HasSwitch(field_trial_handle_switch)) {
- std::string handle_switch =
+ std::string switch_value =
cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
- bool result = CreateTrialsFromHandleSwitch(handle_switch);
+ bool result = CreateTrialsFromSwitchValue(switch_value);
DCHECK(result);
}
#endif
@@ -793,7 +792,9 @@ void FieldTrialList::CreateTrialsFromCommandLine(
// sent over the switch (we don't care about the value). Invalid handles
// occur in some browser tests which don't initialize the allocator.
if (cmd_line.HasSwitch(field_trial_handle_switch)) {
- bool result = CreateTrialsFromDescriptor(fd_key);
+ std::string switch_value =
+ cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
+ bool result = CreateTrialsFromDescriptor(fd_key, switch_value);
DCHECK(result);
}
#endif
@@ -832,21 +833,21 @@ void FieldTrialList::AppendFieldTrialHandleIfNeeded(
return;
if (kUseSharedMemoryForFieldTrials) {
InstantiateFieldTrialAllocatorIfNeeded();
- if (global_->readonly_allocator_handle_)
- handles->push_back(global_->readonly_allocator_handle_);
+ if (global_->readonly_allocator_handle_.IsValid())
+ handles->push_back(global_->readonly_allocator_handle_.GetHandle());
}
}
#endif
#if defined(OS_POSIX) && !defined(OS_NACL)
// static
-int FieldTrialList::GetFieldTrialHandle() {
+SharedMemoryHandle FieldTrialList::GetFieldTrialHandle() {
if (global_ && kUseSharedMemoryForFieldTrials) {
InstantiateFieldTrialAllocatorIfNeeded();
// We check for an invalid handle where this gets called.
return global_->readonly_allocator_handle_;
}
- return kInvalidPlatformFile;
+ return SharedMemoryHandle();
}
#endif
@@ -873,37 +874,16 @@ void FieldTrialList::CopyFieldTrialStateToFlags(
InstantiateFieldTrialAllocatorIfNeeded();
// If the readonly handle didn't get duplicated properly, then fallback to
// original behavior.
- if (global_->readonly_allocator_handle_ == kInvalidPlatformFile) {
+ if (!global_->readonly_allocator_handle_.IsValid()) {
AddFeatureAndFieldTrialFlags(enable_features_switch,
disable_features_switch, cmd_line);
return;
}
global_->field_trial_allocator_->UpdateTrackingHistograms();
-
-#if defined(OS_WIN)
- // We need to pass a named anonymous handle to shared memory over the
- // command line on Windows, since the child doesn't know which of the
- // handles it inherited it should open.
- // PlatformFile is typedef'd to HANDLE which is typedef'd to void *. We
- // basically cast the handle into an int (uintptr_t, to be exact), stringify
- // the int, and pass it as a command-line flag. The child process will do
- // the reverse conversions to retrieve the handle. See
- // http://stackoverflow.com/a/153077
- auto uintptr_handle =
- reinterpret_cast<uintptr_t>(global_->readonly_allocator_handle_);
- std::string field_trial_handle = std::to_string(uintptr_handle);
- cmd_line->AppendSwitchASCII(field_trial_handle_switch, field_trial_handle);
-#elif defined(OS_POSIX)
- // On POSIX, we dup the fd into a fixed fd kFieldTrialDescriptor, so we
- // don't have to pass over the handle (it's not even the right handle
- // anyways). But some browser tests don't create the allocator, so we need
- // to be able to distinguish valid and invalid handles. We do that by just
- // checking that the flag is set with a dummy value.
- cmd_line->AppendSwitchASCII(field_trial_handle_switch, "1");
-#else
-#error Unsupported OS
-#endif
+ std::string switch_value = SerializeSharedMemoryHandleMetadata(
+ global_->readonly_allocator_handle_);
+ cmd_line->AppendSwitchASCII(field_trial_handle_switch, switch_value);
return;
}
@@ -1132,22 +1112,81 @@ FieldTrialList::GetAllFieldTrialsFromPersistentAllocator(
return entries;
}
+// static
+std::string FieldTrialList::SerializeSharedMemoryHandleMetadata(
+ const SharedMemoryHandle& shm) {
+ std::stringstream ss;
+#if defined(OS_WIN)
+ // Tell the child process the name of the inherited HANDLE.
+ uintptr_t uintptr_handle = reinterpret_cast<uintptr_t>(shm.GetHandle());
+ ss << uintptr_handle << ",";
+#elif !defined(OS_POSIX)
+#error Unsupported OS
+#endif
+
+ base::UnguessableToken guid = shm.GetGUID();
+ ss << guid.GetHighForSerialization() << "," << guid.GetLowForSerialization();
+ return ss.str();
+}
+
#if defined(OS_WIN)
// static
-bool FieldTrialList::CreateTrialsFromHandleSwitch(
- const std::string& handle_switch) {
- int field_trial_handle = std::stoi(handle_switch);
+SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata(
+ const std::string& switch_value) {
+ std::vector<base::StringPiece> tokens = base::SplitStringPiece(
+ switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ if (tokens.size() != 3)
+ return SharedMemoryHandle();
+
+ int field_trial_handle = 0;
+ if (!base::StringToInt(tokens[0], &field_trial_handle))
+ return SharedMemoryHandle();
HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle);
- // TODO(erikchen): Plumb a GUID for this SharedMemoryHandle.
- // https://crbug.com/713763.
- SharedMemoryHandle shm_handle(handle, base::UnguessableToken::Create());
- return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle);
+
+ base::UnguessableToken guid;
+ if (!DeserializeGUIDFromStringPieces(tokens[1], tokens[2], &guid))
+ return SharedMemoryHandle();
+
+ return SharedMemoryHandle(handle, guid);
}
-#endif
+#endif // defined(OS_WIN)
+
+#if defined(OS_POSIX) && !defined(OS_NACL)
+// static
+SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata(
+ int fd,
+ const std::string& switch_value) {
+ std::vector<base::StringPiece> tokens = base::SplitStringPiece(
+ switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ if (tokens.size() != 2)
+ return SharedMemoryHandle();
+
+ base::UnguessableToken guid;
+ if (!DeserializeGUIDFromStringPieces(tokens[0], tokens[1], &guid))
+ return SharedMemoryHandle();
+
+ return SharedMemoryHandle(FileDescriptor(fd, true), guid);
+}
+#endif // defined(OS_POSIX) && !defined(OS_NACL)
+
+#if defined(OS_WIN)
+// static
+bool FieldTrialList::CreateTrialsFromSwitchValue(
+ const std::string& switch_value) {
+ SharedMemoryHandle shm = DeserializeSharedMemoryHandleMetadata(switch_value);
+ if (!shm.IsValid())
+ return false;
+ return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm);
+}
+#endif // defined(OS_WIN)
#if defined(OS_POSIX) && !defined(OS_NACL)
// static
-bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) {
+bool FieldTrialList::CreateTrialsFromDescriptor(
+ int fd_key,
+ const std::string& switch_value) {
if (!kUseSharedMemoryForFieldTrials)
return false;
@@ -1158,16 +1197,16 @@ bool FieldTrialList::CreateTrialsFromDescriptor(int fd_key) {
if (fd == -1)
return false;
- // TODO(erikchen): Plumb a GUID for this SharedMemoryHandle.
- // https://crbug.com/713763.
- SharedMemoryHandle shm_handle(FileDescriptor(fd, true),
- base::UnguessableToken::Create());
+ SharedMemoryHandle shm =
+ DeserializeSharedMemoryHandleMetadata(fd, switch_value);
+ if (!shm.IsValid())
+ return false;
- bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm_handle);
+ bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm);
DCHECK(result);
return true;
}
-#endif
+#endif // defined(OS_POSIX) && !defined(OS_NACL)
// static
bool FieldTrialList::CreateTrialsFromSharedMemoryHandle(
@@ -1254,7 +1293,7 @@ void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() {
// Set |readonly_allocator_handle_| so we can pass it to be inherited and
// via the command line.
global_->readonly_allocator_handle_ =
- CreateReadOnlyHandle(global_->field_trial_allocator_.get());
+ global_->field_trial_allocator_->shared_memory()->GetReadOnlyHandle();
#endif
}
« no previous file with comments | « base/metrics/field_trial.h ('k') | base/metrics/field_trial_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698