Chromium Code Reviews| 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, |