| Index: base/synchronization/waitable_event_watcher_win.cc
|
| diff --git a/base/synchronization/waitable_event_watcher_win.cc b/base/synchronization/waitable_event_watcher_win.cc
|
| index f3e114e3966149c610d5579ec69fddaf32555c5f..d28b6a765743cc2cc41d49790be1ca1d0afd58ab 100644
|
| --- a/base/synchronization/waitable_event_watcher_win.cc
|
| +++ b/base/synchronization/waitable_event_watcher_win.cc
|
| @@ -12,26 +12,43 @@ namespace base {
|
|
|
| WaitableEventWatcher::WaitableEventWatcher() = default;
|
|
|
| -WaitableEventWatcher::~WaitableEventWatcher() {
|
| -}
|
| +WaitableEventWatcher::~WaitableEventWatcher() {}
|
|
|
| bool WaitableEventWatcher::StartWatching(WaitableEvent* event,
|
| EventCallback callback) {
|
| + DCHECK(event);
|
| callback_ = std::move(callback);
|
| event_ = event;
|
| - return watcher_.StartWatchingOnce(event->handle(), this);
|
| +
|
| + // Duplicate and hold the event handle until a callback is returned or
|
| + // waiting is stopped.
|
| + HANDLE handle = nullptr;
|
| + if (!::DuplicateHandle(::GetCurrentProcess(), // hSourceProcessHandle
|
| + event->handle(),
|
| + ::GetCurrentProcess(), // hTargetProcessHandle
|
| + &handle,
|
| + 0, // dwDesiredAccess ignored due to SAME_ACCESS
|
| + FALSE, // !bInheritHandle
|
| + DUPLICATE_SAME_ACCESS)) {
|
| + return false;
|
| + }
|
| + duplicated_event_handle_.Set(handle);
|
| + return watcher_.StartWatchingOnce(handle, this);
|
| }
|
|
|
| void WaitableEventWatcher::StopWatching() {
|
| callback_.Reset();
|
| event_ = NULL;
|
| watcher_.StopWatching();
|
| + duplicated_event_handle_.Close();
|
| }
|
|
|
| void WaitableEventWatcher::OnObjectSignaled(HANDLE h) {
|
| + DCHECK_EQ(duplicated_event_handle_.Get(), h);
|
| WaitableEvent* event = event_;
|
| EventCallback callback = std::move(callback_);
|
| event_ = NULL;
|
| + duplicated_event_handle_.Close();
|
| DCHECK(event);
|
|
|
| std::move(callback).Run(event);
|
|
|