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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/conflicts/module_database_win.h"
6
7 #include "base/bind.h"
8 #include "base/debug/leak_annotations.h"
9 #include "base/lazy_instance.h"
10 #include "base/strings/utf_string_conversions.h"
11
12 namespace {
13
14 // Document the assumptions made on the ProcessType enum in order to convert
15 // them to bits.
16 static_assert(1 == content::PROCESS_TYPE_UNKNOWN,
17 "assumes unknown process type has value 1");
18 static_assert(2 == content::PROCESS_TYPE_BROWSER,
19 "assumes unknown browser type has value 2");
20 static constexpr uint32_t kMinProcessType = content::PROCESS_TYPE_BROWSER;
21
22 } // namespace
23
24 ModuleDatabase::ModuleDatabase(
25 scoped_refptr<base::SequencedTaskRunner> task_runner)
26 : task_runner_(task_runner), weak_ptr_factory_(this) {}
27
28 ModuleDatabase::~ModuleDatabase() = default;
29
30 void ModuleDatabase::OnProcessStarted(uint32_t process_id,
31 content::ProcessType process_type) {
32 // Messages can arrive from any thread (UI thread for calls over IPC, and
33 // anywhere at all for calls from ModuleWatcher), so bounce if necessary.
34 if (!task_runner_->RunsTasksOnCurrentThread()) {
35 task_runner_->PostTask(
36 FROM_HERE,
37 base::Bind(&ModuleDatabase::OnProcessStarted,
38 weak_ptr_factory_.GetWeakPtr(), process_id, process_type));
39 return;
40 }
41
42 auto* process_info = CreateProcessInfo(process_id, process_type);
43 // If each client is sending messages in the appropriate order then this
44 // should always be true.
45 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
46 }
47
48 void ModuleDatabase::OnModuleEvent(uint32_t process_id,
49 const mojom::ModuleEvent& event) {
50 // Messages can arrive from any thread (UI thread for calls over IPC, and
51 // anywhere at all for calls from ModuleWatcher), so bounce if necessary.
52 if (!task_runner_->RunsTasksOnCurrentThread()) {
53 task_runner_->PostTask(FROM_HERE, base::Bind(&ModuleDatabase::OnModuleEvent,
54 weak_ptr_factory_.GetWeakPtr(),
55 process_id, event));
56 return;
57 }
58
59 base::FilePath module_path(base::UTF8ToWide(event.module_path));
60 auto* module_info = FindOrCreateModuleInfo(module_path);
61
62 // In theory this should always succeed. However, it is possible for a client
63 // to misbehave and sent out-of-order messages. It is easy to be tolerant of
64 // this case by simply not updating the process info in this case. It's not
65 // 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.... :-)
66 // informational.
67 auto* process_info = GetProcessInfo(process_id);
68 DCHECK(process_info);
69 if (!process_info)
70 return;
71
72 // Update the list of process types that this module has been seen in.
73 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.
74 module_info->process_types |= process_type_bit;
75
76 // Update the module lists for this process.
77 switch (event.event_type) {
78 case mojom::ModuleEventType::MODULE_ALREADY_LOADED:
79 case mojom::ModuleEventType::MODULE_LOADED:
80 process_info->loaded_module_ids.insert(module_info->module_id);
81 break;
82 case mojom::ModuleEventType::MODULE_UNLOADED:
83 process_info->loaded_module_ids.erase(module_info->module_id);
84 process_info->unloaded_module_ids.insert(module_info->module_id);
85 break;
86 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.
87 NOTREACHED() << "Unknown ModuleEventType: " << event.event_type;
88 }
89 }
90
91 void ModuleDatabase::OnProcessEnded(uint32_t process_id) {
92 // Messages can arrive from any thread (UI thread for calls over IPC, and
93 // anywhere at all for calls from ModuleWatcher), so bounce if necessary.
94 if (!task_runner_->RunsTasksOnCurrentThread()) {
95 task_runner_->PostTask(
96 FROM_HERE, base::Bind(&ModuleDatabase::OnProcessEnded,
97 weak_ptr_factory_.GetWeakPtr(), process_id));
98 return;
99 }
100
101 bool deleted = DeleteProcessInfo(process_id);
102 // If each client is sending messages in the appropriate order then this
103 // should always be true.
104 DCHECK(deleted);
105 }
106
107 // static
108 uint32_t ModuleDatabase::ProcessTypeToBit(content::ProcessType process_type) {
109 uint32_t bit_index = static_cast<uint32_t>(process_type) - kMinProcessType;
110 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
111 DCHECK_GE(31u, bit_index);
112 uint32_t bit = (1 << bit_index);
113 return bit;
114 }
115
116 // static
117 content::ProcessType ModuleDatabase::BitIndexToProcessType(uint32_t bit_index) {
118 DCHECK_LE(0u, bit_index);
119 DCHECK_GE(31u, bit_index);
120 return static_cast<content::ProcessType>(bit_index + kMinProcessType);
121 }
122
123 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
124 uint32_t module_id)
125 : module_path(module_path), module_id(module_id), process_types(0) {}
126
127 bool ModuleDatabase::ModuleInfoKeyComparator::operator()(
128 const ModuleInfo& mi1,
129 const ModuleInfo& mi2) const {
130 return mi1.module_path < mi2.module_path;
131 }
132
133 ModuleDatabase::ProcessInfo::ProcessInfo(uint32_t process_id,
134 content::ProcessType process_type)
135 : process_id(process_id), process_type(process_type) {}
136
137 bool ModuleDatabase::ProcessInfoKeyComparator::operator()(
138 const ProcessInfo& pi1,
139 const ProcessInfo& pi2) const {
140 return pi1.process_id < pi2.process_id;
141 }
142
143 ModuleDatabase::ModuleInfo* ModuleDatabase::FindOrCreateModuleInfo(
144 const base::FilePath& module_path) {
145 ModuleInfo key(module_path, modules_.size());
146 auto result = modules_.insert(key);
147 return const_cast<ModuleInfo*>(&(*result.first));
148 }
149
150 ModuleDatabase::ProcessInfo* ModuleDatabase::GetProcessInfo(
151 uint32_t process_id) {
152 ProcessInfo key(process_id, content::PROCESS_TYPE_UNKNOWN);
153 auto it = processes_.find(key);
154 if (it == processes_.end())
155 return nullptr;
156 return const_cast<ProcessInfo*>(&(*it));
157 }
158
159 const ModuleDatabase::ProcessInfo* ModuleDatabase::CreateProcessInfo(
160 uint32_t process_id,
161 content::ProcessType process_type) {
162 ProcessInfo key(process_id, process_type);
163 auto result = processes_.insert(key);
164
165 // If the element was inserted then return it.
166 if (result.second)
167 return &(*result.first);
168 // Otherwise it already existed, so return nullptr.
169 return nullptr;
170 }
171
172 bool ModuleDatabase::DeleteProcessInfo(uint32_t process_id) {
173 ProcessInfo key(process_id, content::PROCESS_TYPE_UNKNOWN);
174 auto it = processes_.find(key);
175 if (it == processes_.end())
176 return false;
177 processes_.erase(it);
178 return true;
179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698