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

Unified Diff: chrome/browser/conflicts/module_database_win.cc

Issue 2576843002: [win] Create ModuleDatabase and ModuleEventSinkImpl. (Closed)
Patch Set: Created 4 years 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
Index: chrome/browser/conflicts/module_database_win.cc
diff --git a/chrome/browser/conflicts/module_database_win.cc b/chrome/browser/conflicts/module_database_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8b020cbf2ebf2993dcaef880b028c864962add6e
--- /dev/null
+++ b/chrome/browser/conflicts/module_database_win.cc
@@ -0,0 +1,179 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/conflicts/module_database_win.h"
+
+#include "base/bind.h"
+#include "base/debug/leak_annotations.h"
+#include "base/lazy_instance.h"
+#include "base/strings/utf_string_conversions.h"
+
+namespace {
+
+// Document the assumptions made on the ProcessType enum in order to convert
+// them to bits.
+static_assert(1 == content::PROCESS_TYPE_UNKNOWN,
+ "assumes unknown process type has value 1");
+static_assert(2 == content::PROCESS_TYPE_BROWSER,
+ "assumes unknown browser type has value 2");
+static constexpr uint32_t kMinProcessType = content::PROCESS_TYPE_BROWSER;
+
+} // namespace
+
+ModuleDatabase::ModuleDatabase(
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : task_runner_(task_runner), weak_ptr_factory_(this) {}
+
+ModuleDatabase::~ModuleDatabase() = default;
+
+void ModuleDatabase::OnProcessStarted(uint32_t process_id,
+ content::ProcessType process_type) {
+ // Messages can arrive from any thread (UI thread for calls over IPC, and
+ // anywhere at all for calls from ModuleWatcher), so bounce if necessary.
+ if (!task_runner_->RunsTasksOnCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&ModuleDatabase::OnProcessStarted,
+ weak_ptr_factory_.GetWeakPtr(), process_id, process_type));
+ return;
+ }
+
+ auto* process_info = CreateProcessInfo(process_id, process_type);
+ // If each client is sending messages in the appropriate order then this
+ // should always be true.
+ DCHECK(process_info);
sky 2016/12/14 21:58:08 Doesn't this really depend upon how fast messages
chrisha 2016/12/19 20:15:36 Yes, this indeed could depend on the order in whic
+}
+
+void ModuleDatabase::OnModuleEvent(uint32_t process_id,
+ const mojom::ModuleEvent& event) {
+ // Messages can arrive from any thread (UI thread for calls over IPC, and
+ // anywhere at all for calls from ModuleWatcher), so bounce if necessary.
+ if (!task_runner_->RunsTasksOnCurrentThread()) {
+ task_runner_->PostTask(FROM_HERE, base::Bind(&ModuleDatabase::OnModuleEvent,
+ weak_ptr_factory_.GetWeakPtr(),
+ process_id, event));
+ return;
+ }
+
+ base::FilePath module_path(base::UTF8ToWide(event.module_path));
+ auto* module_info = FindOrCreateModuleInfo(module_path);
+
+ // In theory this should always succeed. However, it is possible for a client
+ // to misbehave and sent out-of-order messages. It is easy to be tolerant of
+ // this case by simply not updating the process info in this case. It's not
+ // worth crashing if this data is slightly out of sync as this is purely
grt (UTC plus 2) 2016/12/15 09:07:12 if it's not worth crashing, why is there a DCHECK?
chrisha 2016/12/19 20:15:36 Not worth crashing at all. Removed.
grt (UTC plus 2) 2016/12/20 11:11:33 Maybe, maybe not.... :-)
+ // informational.
+ auto* process_info = GetProcessInfo(process_id);
+ DCHECK(process_info);
+ if (!process_info)
+ return;
+
+ // Update the list of process types that this module has been seen in.
+ uint32_t process_type_bit = ProcessTypeToBit(process_info->process_type);
grt (UTC plus 2) 2016/12/15 09:07:12 nit: omit variable
chrisha 2016/12/19 20:15:36 Done.
+ module_info->process_types |= process_type_bit;
+
+ // Update the module lists for this process.
+ switch (event.event_type) {
+ case mojom::ModuleEventType::MODULE_ALREADY_LOADED:
+ case mojom::ModuleEventType::MODULE_LOADED:
+ process_info->loaded_module_ids.insert(module_info->module_id);
+ break;
+ case mojom::ModuleEventType::MODULE_UNLOADED:
+ process_info->loaded_module_ids.erase(module_info->module_id);
+ process_info->unloaded_module_ids.insert(module_info->module_id);
+ break;
+ default:
grt (UTC plus 2) 2016/12/15 09:07:12 remove this so that compilation will fail if a new
chrisha 2016/12/19 20:15:36 Done.
+ NOTREACHED() << "Unknown ModuleEventType: " << event.event_type;
+ }
+}
+
+void ModuleDatabase::OnProcessEnded(uint32_t process_id) {
+ // Messages can arrive from any thread (UI thread for calls over IPC, and
+ // anywhere at all for calls from ModuleWatcher), so bounce if necessary.
+ if (!task_runner_->RunsTasksOnCurrentThread()) {
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&ModuleDatabase::OnProcessEnded,
+ weak_ptr_factory_.GetWeakPtr(), process_id));
+ return;
+ }
+
+ bool deleted = DeleteProcessInfo(process_id);
+ // If each client is sending messages in the appropriate order then this
+ // should always be true.
+ DCHECK(deleted);
+}
+
+// static
+uint32_t ModuleDatabase::ProcessTypeToBit(content::ProcessType process_type) {
+ uint32_t bit_index = static_cast<uint32_t>(process_type) - kMinProcessType;
+ DCHECK_LE(0u, bit_index);
grt (UTC plus 2) 2016/12/15 09:07:12 nit: i find these more natural the other way aroun
chrisha 2016/12/19 20:15:36 I'm impartial, but over the years had reviewers dr
grt (UTC plus 2) 2016/12/20 11:11:33 I apologize if I was a driller in the past, but I
+ DCHECK_GE(31u, bit_index);
+ uint32_t bit = (1 << bit_index);
+ return bit;
+}
+
+// static
+content::ProcessType ModuleDatabase::BitIndexToProcessType(uint32_t bit_index) {
+ DCHECK_LE(0u, bit_index);
+ DCHECK_GE(31u, bit_index);
+ return static_cast<content::ProcessType>(bit_index + kMinProcessType);
+}
+
+ModuleDatabase::ModuleInfo::ModuleInfo(const base::FilePath& module_path,
grt (UTC plus 2) 2016/12/15 09:07:12 nit: keep class function definitions grouped by cl
chrisha 2016/12/19 20:15:36 I had kept the declarations and definitions in the
+ uint32_t module_id)
+ : module_path(module_path), module_id(module_id), process_types(0) {}
+
+bool ModuleDatabase::ModuleInfoKeyComparator::operator()(
+ const ModuleInfo& mi1,
+ const ModuleInfo& mi2) const {
+ return mi1.module_path < mi2.module_path;
+}
+
+ModuleDatabase::ProcessInfo::ProcessInfo(uint32_t process_id,
+ content::ProcessType process_type)
+ : process_id(process_id), process_type(process_type) {}
+
+bool ModuleDatabase::ProcessInfoKeyComparator::operator()(
+ const ProcessInfo& pi1,
+ const ProcessInfo& pi2) const {
+ return pi1.process_id < pi2.process_id;
+}
+
+ModuleDatabase::ModuleInfo* ModuleDatabase::FindOrCreateModuleInfo(
+ const base::FilePath& module_path) {
+ ModuleInfo key(module_path, modules_.size());
+ auto result = modules_.insert(key);
+ return const_cast<ModuleInfo*>(&(*result.first));
+}
+
+ModuleDatabase::ProcessInfo* ModuleDatabase::GetProcessInfo(
+ uint32_t process_id) {
+ ProcessInfo key(process_id, content::PROCESS_TYPE_UNKNOWN);
+ auto it = processes_.find(key);
+ if (it == processes_.end())
+ return nullptr;
+ return const_cast<ProcessInfo*>(&(*it));
+}
+
+const ModuleDatabase::ProcessInfo* ModuleDatabase::CreateProcessInfo(
+ uint32_t process_id,
+ content::ProcessType process_type) {
+ ProcessInfo key(process_id, process_type);
+ auto result = processes_.insert(key);
+
+ // If the element was inserted then return it.
+ if (result.second)
+ return &(*result.first);
+ // Otherwise it already existed, so return nullptr.
+ return nullptr;
+}
+
+bool ModuleDatabase::DeleteProcessInfo(uint32_t process_id) {
+ ProcessInfo key(process_id, content::PROCESS_TYPE_UNKNOWN);
+ auto it = processes_.find(key);
+ if (it == processes_.end())
+ return false;
+ processes_.erase(it);
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698