1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/synchronization/waitable_event_watcher.h"
6
7 #include <windows.h>
8
9 #include "base/compiler_specific.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/win/object_watcher.h"
12
13 namespace base {
14
15 WaitableEventWatcher::WaitableEventWatcher() = default;
16
~WaitableEventWatcher()17 WaitableEventWatcher::~WaitableEventWatcher() {}
18
StartWatching(WaitableEvent * event,EventCallback callback,scoped_refptr<SequencedTaskRunner> task_runner)19 bool WaitableEventWatcher::StartWatching(
20 WaitableEvent* event,
21 EventCallback callback,
22 scoped_refptr<SequencedTaskRunner> task_runner) {
23 DCHECK(event);
24 callback_ = std::move(callback);
25 event_ = event;
26
27 // Duplicate and hold the event handle until a callback is returned or
28 // waiting is stopped.
29 HANDLE handle = nullptr;
30 if (!::DuplicateHandle(::GetCurrentProcess(), // hSourceProcessHandle
31 event->handle(),
32 ::GetCurrentProcess(), // hTargetProcessHandle
33 &handle,
34 0, // dwDesiredAccess ignored due to SAME_ACCESS
35 FALSE, // !bInheritHandle
36 DUPLICATE_SAME_ACCESS)) {
37 return false;
38 }
39 duplicated_event_handle_.Set(handle);
40 return watcher_.StartWatchingOnce(handle, this);
41 }
42
StopWatching()43 void WaitableEventWatcher::StopWatching() {
44 callback_.Reset();
45 event_ = nullptr;
46 watcher_.StopWatching();
47 duplicated_event_handle_.Close();
48 }
49
OnObjectSignaled(HANDLE h)50 void WaitableEventWatcher::OnObjectSignaled(HANDLE h) {
51 DCHECK_EQ(duplicated_event_handle_.get(), h);
52 WaitableEvent* event = event_;
53 EventCallback callback = std::move(callback_);
54 event_ = nullptr;
55 duplicated_event_handle_.Close();
56 DCHECK(event);
57
58 std::move(callback).Run(event);
59 }
60
61 } // namespace base
62