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

Unified Diff: chrome/common/conflicts/module_watcher_win.h

Issue 2473783005: [Win] Create ModuleWatcher. (Closed)
Patch Set: 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/conflicts/module_watcher_win.h
diff --git a/chrome/common/conflicts/module_watcher_win.h b/chrome/common/conflicts/module_watcher_win.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd7c4bc20fa7c2fb4b25b84462ebc5c00d58b27a
--- /dev/null
+++ b/chrome/common/conflicts/module_watcher_win.h
@@ -0,0 +1,156 @@
+// 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.
+
+#ifndef CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_
+#define CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+
+namespace base {
+template <class ObserverType>
+class ObserverListThreadSafe;
+} // namespace base
+
+namespace conflicts {
+
+class ModuleWatcherTest;
+
+// This class observes modules as they are loaded and unloaded into a processes
+// address space. It works by installing a DllNotification callback, and
+// also enumerating all currently loaded modules at the time of its creation.
+class ModuleWatcher {
+ public:
+ // The types of events that are observed by the watcher.
+ enum EventType {
+ // The module was already loaded at the time of creation of the
+ // ModuleWatcher.
+ MODULE_ALREADY_LOADED,
+ // The module was not loaded at the time of creation of the ModuleWatcher
+ // and is being loaded.
+ MODULE_LOADED,
+ // The module is being unloaded.
+ MODULE_UNLOADED,
+ };
+
+ // A notification about a module being loaded or unloaded.
+ struct ModuleEvent {
+ // The type of event.
+ EventType event_type;
+ // The full path to the module being loaded or unloaded.
+ base::FilePath module_path;
+ // The load address of the module.
+ void* load_address;
+ // The size of the module in memory, in bytes.
+ size_t size;
+ };
+
+ // Clients may register callbacks with the following type in order to receive
+ // notifications.
+ using OnModuleEventCallback = base::Callback<void(const ModuleEvent& event)>;
+ class Observer;
+
+ ModuleWatcher();
+ ~ModuleWatcher();
+
+ // Registers a callback with this ModuleWatcher. The thread on which the
+ // callback is registered is the thread on which the callback will be invoked.
+ // To unregister the callback simply delete the resulting Observer object.
+ // Note that the observer must be destroyed on the same thread on which it
+ // was created. (See ObserverListThreadSafe::RemoveObserver for details.)
+ std::unique_ptr<Observer> RegisterCallback(
Patrick Monette 2016/11/03 20:18:15 Seems like you are implementing base::CallbackList
chrisha 2016/11/04 15:32:42 I am indeed. I'm not sure if anybody else needs th
+ const OnModuleEventCallback& callback);
+
+ // Starts the watcher. This enumerates all loaded modules and registers a
+ // DllNotification callback for continued notifications. This is threadsafe.
+ // Note that it is possible to receive duplicate notifications for some
+ // modules as the initial loaded module enumerations is racy with the
+ // installation of the callback. In this case you will receive both a
+ // MODULE_LOADED and a MODULE_ALREADY_LOADED event for the same module. Since
+ // the callback is installed first no modules will be missed.
+ void Start();
+
+ // Stops the watcher. The watcher may subsequently be restarted. Doesn't
+ // need to be called explicitly as ~ModuleWatcher will do so as well. This
+ // is thread-safe.
+ void Stop();
+
+ // Returns true if the watcher is currently running, false otherwise.
+ bool IsRunning();
+
+ protected:
+ // Used as a bridge between the operating system notifications and this class.
+ class Bridge;
+
+ // The Bridge requires access to Notify.
+ friend class Bridge;
+ // For unittesting.
+ friend class ModuleWatcherTest;
+ // Observers require access to |observer_list_|.
+ friend class Observer;
+
+ // Registers a Dll Notification callback with the OS. Returns true on success,
+ // false otherwise. Modifies |dll_notification_cookie_|.
+ bool RegisterDllNotificationCallback();
+
+ // Removes the installed Dll Notification callback. This should only
+ // be called if InstallDllNotificationCallback returned true. Returns true on
+ // success, false otherwise.
+ bool UnregisterDllNotificationCallback();
+
+ // Enumerates all currently loaded modules, firing off callbacks. Returns
+ // true on success, false otherwise.
+ bool EnumerateAlreadyLoadedModules();
+
+ // Invoked by ModuleWatcherHelper. Dispatches the provided ModuleEvent to all
+ // registered observers.
+ void Notify(const ModuleEvent& event);
+
+ // The list of registered observers. This is directly modified by
+ // ModuleWatcher::Observer.
+ scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_;
+
+ private:
+ base::Lock lock_;
+ // Indicates whether or not the ModuleWatcher is currently started. Under
+ // lock_.
+ bool started_;
+ // Used by the DllNotification mechanism. Under lock_.
+ void* dll_notification_cookie_;
+
+ DISALLOW_COPY_AND_ASSIGN(ModuleWatcher);
+};
+
+// Observer class. This is all implementation detail, plumbing callbacks to
+// an ObserverListThreadSafe and handling automatic unregistration. Nothing to
+// see here.
+class ModuleWatcher::Observer {
+ public:
+ ~Observer();
+
+ protected:
+ friend ModuleWatcher;
+
+ // Constructor. To actually create one of these use
+ // ModuleWatcher::RegisterCallback
+ Observer(const OnModuleEventCallback& callback,
+ ModuleWatcher* module_watcher);
+
+ // Used by ModuleWatcher to dispatch events to this observer.
+ void Notify(const ModuleEvent& event);
+
+ // The bound callback.
+ OnModuleEventCallback callback_;
+ // The parent ModuleWatcher to which this observer belongs.
+ ModuleWatcher* module_watcher_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Observer);
+};
+
+} // namespace conflicts
+
+#endif // CHROME_COMMON_CONFLICTS_MODULE_WATCHER_WIN_H_

Powered by Google App Engine
This is Rietveld 408576698