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

Side by Side Diff: chrome/common/conflicts/module_watcher_win.h

Issue 2473783005: [Win] Create ModuleWatcher. (Closed)
Patch Set: Address pmonette's comments. Created 4 years, 1 month 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 #ifndef CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_
6 #define CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_
7
8 #include "base/callback.h"
9 #include "base/files/file_path.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/synchronization/lock.h"
12
13 namespace base {
14 template <class ObserverType>
15 class ObserverListThreadSafe;
16 } // namespace base
17
18 namespace conflicts {
19
20 class ModuleWatcherTest;
21
22 // This class observes modules as they are loaded and unloaded into a process'
23 // address space. It works by installing a DllNotification callback, and
24 // also enumerating all currently loaded modules at the time of its creation.
25 // It doesn't really make sense to create more than one of these in a process,
26 // although it's entirely possible.
27 class ModuleWatcher {
28 public:
29 // The types of events that are observed by the watcher.
30 enum EventType {
sky 2016/11/04 16:27:24 Generally favor enum class for new code.
chrisha 2016/11/04 19:15:49 Good point. I'll actually be moving this in a Mojo
31 // The module was already loaded at the time of creation of the
32 // ModuleWatcher.
33 MODULE_ALREADY_LOADED,
34 // The module was not loaded at the time of creation of the ModuleWatcher
35 // and is being loaded.
36 MODULE_LOADED,
37 // The module is being unloaded.
38 MODULE_UNLOADED,
39 };
40
41 // A notification about a module being loaded or unloaded.
42 struct ModuleEvent {
43 // The type of event.
44 EventType event_type;
45 // The full path to the module being loaded or unloaded.
46 base::FilePath module_path;
47 // The load address of the module.
48 void* load_address;
49 // The size of the module in memory, in bytes.
50 size_t size;
51 };
52
53 // Clients may register callbacks with the following type in order to receive
54 // notifications.
55 using OnModuleEventCallback = base::Callback<void(const ModuleEvent& event)>;
56 class Observer;
57
58 ModuleWatcher();
59 ~ModuleWatcher();
60
61 // Registers a callback with this ModuleWatcher. The thread on which the
sky 2016/11/04 16:27:24 Can you motivate why you need the threading comple
chrisha 2016/11/04 19:15:49 The problem is with the LdrDllNotification callbac
62 // callback is registered is the thread on which the callback will be invoked.
63 // To unregister the callback simply delete the resulting Observer object.
64 // Note that the observer must be destroyed on the same thread on which it
65 // was created. (See ObserverListThreadSafe::RemoveObserver for details.)
66 // NOTE: This is a wrapper around ObserverListThreadSafe that effectively
67 // creates a CallbackListThreadSafe. If anybody goes looking for such a thing
68 // and stumbles upon this code, contact chrisha@ about generalizing it.
69 std::unique_ptr<Observer> RegisterCallback(
sky 2016/11/04 16:27:24 Generally in chrome code and Observer is an interf
chrisha 2016/11/04 19:15:49 Yeah, or "Subscription" if I want to follow the Ca
70 const OnModuleEventCallback& callback);
71
72 // Starts the watcher. This enumerates all loaded modules and registers a
73 // DllNotification callback for continued notifications. This is threadsafe.
74 // Note that it is possible to receive duplicate notifications for some
75 // modules as the initial loaded module enumerations is racy with the
76 // installation of the callback. In this case you will receive both a
77 // MODULE_LOADED and a MODULE_ALREADY_LOADED event for the same module. Since
78 // the callback is installed first no modules will be missed.
79 void Start();
80
81 // Stops the watcher. The watcher may subsequently be restarted. Doesn't
82 // need to be called explicitly as ~ModuleWatcher will do so as well. This
83 // is thread-safe.
84 void Stop();
85
86 // Returns true if the watcher is currently running, false otherwise.
87 bool IsRunning();
88
89 protected:
90 // Used as a bridge between the operating system notifications and this class.
91 class Bridge;
92
93 // The Bridge requires access to Notify.
94 friend class Bridge;
95 // For unittesting.
96 friend class ModuleWatcherTest;
97 // Observers require access to |observer_list_|.
98 friend class Observer;
99
100 // Registers a Dll Notification callback with the OS. Returns true on success,
101 // false otherwise. Modifies |dll_notification_cookie_|. Requires |lock_| to
102 // already be acquired.
103 bool RegisterDllNotificationCallback();
104
105 // Removes the installed Dll Notification callback. This should only
106 // be called if InstallDllNotificationCallback returned true. Returns true on
107 // success, false otherwise. Requires |lock_| to already be acquired.
108 bool UnregisterDllNotificationCallback();
109
110 // Enumerates all currently loaded modules, firing off callbacks. Returns
111 // true on success, false otherwise.
112 bool EnumerateAlreadyLoadedModules();
113
114 // Invoked by ModuleWatcherHelper. Dispatches the provided ModuleEvent to all
115 // registered observers.
116 void Notify(const ModuleEvent& event);
117
118 // The list of registered observers. This is directly modified by
119 // ModuleWatcher::Observer.
120 scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_;
121
122 private:
123 base::Lock lock_;
124 // Indicates whether or not the ModuleWatcher is currently started. Under
125 // lock_.
126 bool started_;
127 // Used by the DllNotification mechanism. Under lock_.
128 void* dll_notification_cookie_;
129
130 DISALLOW_COPY_AND_ASSIGN(ModuleWatcher);
131 };
132
133 // Observer class. This is all implementation detail, plumbing callbacks to
134 // an ObserverListThreadSafe and handling automatic unregistration. Nothing to
135 // see here.
136 class ModuleWatcher::Observer {
137 public:
138 ~Observer();
139
140 protected:
141 friend ModuleWatcher;
142
143 // Constructor. To actually create one of these use
144 // ModuleWatcher::RegisterCallback
145 Observer(const OnModuleEventCallback& callback,
146 ModuleWatcher* module_watcher);
147
148 // Used by ModuleWatcher to dispatch events to this observer.
149 void Notify(const ModuleEvent& event);
150
151 // The bound callback.
152 OnModuleEventCallback callback_;
sky 2016/11/04 16:27:24 Style guide says no protected members.
153 // The parent ModuleWatcher to which this observer belongs.
154 ModuleWatcher* module_watcher_;
155
156 private:
157 DISALLOW_COPY_AND_ASSIGN(Observer);
158 };
159
160 } // namespace conflicts
161
162 #endif // CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698