Index: base/win/registry.cc |
diff --git a/base/win/registry.cc b/base/win/registry.cc |
index a6cb9ae89f789a78461e7d611374e603f492b724..7e1636b0ed4883db6e851fbf193c2497ef7f8e86 100644 |
--- a/base/win/registry.cc |
+++ b/base/win/registry.cc |
@@ -34,23 +34,30 @@ const REGSAM kWow64AccessMask = KEY_WOW64_32KEY | KEY_WOW64_64KEY; |
} // namespace |
+class RegKey::WatcherDelegate : public ObjectWatcher::Delegate { |
+ public: |
+ explicit WatcherDelegate(RegKey* owner) : owner_(owner) {} |
+ |
+ // Implementation of ObjectWatcher::Delegate. |
+ void OnObjectSignaled(HANDLE object) override { |
+ owner_->OnObjectSignaled(object); |
+ } |
+ |
+ private: |
cpu_(ooo_6.6-7.5)
2014/10/08 23:28:19
now that you have this helper guy seems we want th
rvargas (doing something else)
2014/10/09 00:22:46
done
I wanted a trivial adaptor between a delegat
|
+ RegKey* owner_; |
+}; |
+ |
+ |
// RegKey ---------------------------------------------------------------------- |
-RegKey::RegKey() |
- : key_(NULL), |
- watch_event_(0), |
- wow64access_(0) { |
+RegKey::RegKey() : key_(NULL), wow64access_(0) { |
} |
-RegKey::RegKey(HKEY key) |
- : key_(key), |
- watch_event_(0), |
- wow64access_(0) { |
+RegKey::RegKey(HKEY key) : key_(key), wow64access_(0) { |
} |
RegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) |
: key_(NULL), |
- watch_event_(0), |
wow64access_(0) { |
if (rootkey) { |
if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) |
@@ -150,7 +157,6 @@ LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) { |
} |
void RegKey::Close() { |
- StopWatching(); |
if (key_) { |
::RegCloseKey(key_); |
key_ = NULL; |
@@ -168,7 +174,6 @@ void RegKey::Set(HKEY key) { |
HKEY RegKey::Take() { |
DCHECK(wow64access_ == 0); |
- StopWatching(); |
HKEY key = key_; |
key_ = NULL; |
return key; |
@@ -367,10 +372,37 @@ LONG RegKey::WriteValue(const wchar_t* name, |
return result; |
} |
-LONG RegKey::StartWatching() { |
+bool RegKey::StartWatching(const ChangeCallback& callback) { |
+ DCHECK(callback_.is_null()); |
+ if (!StartWatchingInternal()) |
+ return false; |
+ |
+ DCHECK(watch_event_.IsValid()); |
+ if (!watcher_delegate_) |
+ watcher_delegate_.reset(new WatcherDelegate(this)); |
+ |
+ if (!object_watcher_.StartWatching(watch_event_.Get(), |
+ watcher_delegate_.get())) { |
+ return false; |
+ } |
+ |
+ callback_ = callback; |
+ return true; |
+} |
+ |
+bool RegKey::StartWatchingInternal() { |
DCHECK(key_); |
- if (!watch_event_) |
- watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); |
+ if (GetVersion() < VERSION_VISTA) { |
+ // It is an error to register multiple times before Vista. |
+ if (watch_event_.IsValid()) |
+ return true; |
+ } |
+ |
+ if (!watch_event_.IsValid()) |
+ watch_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); |
+ |
+ if (!watch_event_.IsValid()) |
+ return false; |
DWORD filter = REG_NOTIFY_CHANGE_NAME | |
REG_NOTIFY_CHANGE_ATTRIBUTES | |
@@ -378,33 +410,14 @@ LONG RegKey::StartWatching() { |
REG_NOTIFY_CHANGE_SECURITY; |
// Watch the registry key for a change of value. |
- LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE); |
+ LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_.Get(), |
+ TRUE); |
if (result != ERROR_SUCCESS) { |
- CloseHandle(watch_event_); |
- watch_event_ = 0; |
+ watch_event_.Close(); |
+ return false; |
} |
- return result; |
-} |
- |
-bool RegKey::HasChanged() { |
- if (watch_event_) { |
- if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { |
- StartWatching(); |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-LONG RegKey::StopWatching() { |
- LONG result = ERROR_INVALID_HANDLE; |
- if (watch_event_) { |
- CloseHandle(watch_event_); |
- watch_event_ = 0; |
- result = ERROR_SUCCESS; |
- } |
- return result; |
+ return true; |
} |
// static |
@@ -484,6 +497,13 @@ LONG RegKey::RegDelRecurse(HKEY root_key, |
return result; |
} |
+void RegKey::OnObjectSignaled(HANDLE object) { |
+ DCHECK(watch_event_.IsValid() && watch_event_.Get() == object); |
+ ChangeCallback callback = callback_; |
+ callback_.Reset(); |
+ callback.Run(); |
+} |
+ |
// RegistryValueIterator ------------------------------------------------------ |
RegistryValueIterator::RegistryValueIterator(HKEY root_key, |