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

Side by Side Diff: base/win/object_watcher.cc

Issue 2125763003: Remove MessageLoop::current() from base::win::ObjectWatcher. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR grt #12 (comments) Created 4 years, 5 months 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 unified diff | Download patch
« no previous file with comments | « base/win/object_watcher.h ('k') | chrome/common/service_process_util_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/win/object_watcher.h" 5 #include "base/win/object_watcher.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/threading/thread_task_runner_handle.h"
9 10
10 namespace base { 11 namespace base {
11 namespace win { 12 namespace win {
12 13
13 //----------------------------------------------------------------------------- 14 //-----------------------------------------------------------------------------
14 15
15 ObjectWatcher::ObjectWatcher() 16 ObjectWatcher::ObjectWatcher() : weak_factory_(this) {}
16 : object_(NULL),
17 wait_object_(NULL),
18 origin_loop_(NULL),
19 run_once_(true),
20 weak_factory_(this) {
21 }
22 17
23 ObjectWatcher::~ObjectWatcher() { 18 ObjectWatcher::~ObjectWatcher() {
24 StopWatching(); 19 StopWatching();
25 } 20 }
26 21
27 bool ObjectWatcher::StartWatchingOnce(HANDLE object, Delegate* delegate) { 22 bool ObjectWatcher::StartWatchingOnce(HANDLE object, Delegate* delegate) {
28 return StartWatchingInternal(object, delegate, true); 23 return StartWatchingInternal(object, delegate, true);
29 } 24 }
30 25
31 bool ObjectWatcher::StartWatchingMultipleTimes(HANDLE object, 26 bool ObjectWatcher::StartWatchingMultipleTimes(HANDLE object,
32 Delegate* delegate) { 27 Delegate* delegate) {
33 return StartWatchingInternal(object, delegate, false); 28 return StartWatchingInternal(object, delegate, false);
34 } 29 }
35 30
36 bool ObjectWatcher::StopWatching() { 31 bool ObjectWatcher::StopWatching() {
37 if (!wait_object_) 32 if (!wait_object_)
38 return false; 33 return false;
39 34
40 // Make sure ObjectWatcher is used in a single-threaded fashion. 35 // Make sure ObjectWatcher is used in a single-threaded fashion.
41 DCHECK_EQ(origin_loop_, MessageLoop::current()); 36 DCHECK(task_runner_->BelongsToCurrentThread());
42 37
43 // Blocking call to cancel the wait. Any callbacks already in progress will 38 // Blocking call to cancel the wait. Any callbacks already in progress will
44 // finish before we return from this call. 39 // finish before we return from this call.
45 if (!UnregisterWaitEx(wait_object_, INVALID_HANDLE_VALUE)) { 40 if (!UnregisterWaitEx(wait_object_, INVALID_HANDLE_VALUE)) {
46 DPLOG(FATAL) << "UnregisterWaitEx failed"; 41 DPLOG(FATAL) << "UnregisterWaitEx failed";
47 return false; 42 return false;
48 } 43 }
49 44
50 weak_factory_.InvalidateWeakPtrs(); 45 Reset();
51 object_ = NULL;
52 wait_object_ = NULL;
53
54 origin_loop_->RemoveDestructionObserver(this);
55 return true; 46 return true;
56 } 47 }
57 48
58 bool ObjectWatcher::IsWatching() const { 49 bool ObjectWatcher::IsWatching() const {
59 return object_ != NULL; 50 return object_ != nullptr;
60 } 51 }
61 52
62 HANDLE ObjectWatcher::GetWatchedObject() const { 53 HANDLE ObjectWatcher::GetWatchedObject() const {
63 return object_; 54 return object_;
64 } 55 }
65 56
66 // static 57 // static
67 void CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) { 58 void CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) {
68 DCHECK(!timed_out); 59 DCHECK(!timed_out);
69 60
70 // The destructor blocks on any callbacks that are in flight, so we know that 61 // The destructor blocks on any callbacks that are in flight, so we know that
71 // that is always a pointer to a valid ObjectWater. 62 // that is always a pointer to a valid ObjectWater.
72 ObjectWatcher* that = static_cast<ObjectWatcher*>(param); 63 ObjectWatcher* that = static_cast<ObjectWatcher*>(param);
73 that->origin_loop_->task_runner()->PostTask(FROM_HERE, that->callback_); 64 that->task_runner_->PostTask(FROM_HERE, that->callback_);
74 if (that->run_once_) 65 if (that->run_once_)
75 that->callback_.Reset(); 66 that->callback_.Reset();
76 } 67 }
77 68
78 bool ObjectWatcher::StartWatchingInternal(HANDLE object, Delegate* delegate, 69 bool ObjectWatcher::StartWatchingInternal(HANDLE object, Delegate* delegate,
79 bool execute_only_once) { 70 bool execute_only_once) {
80 CHECK(delegate); 71 DCHECK(delegate);
81 if (wait_object_) { 72 DCHECK(!wait_object_) << "Already watching an object";
82 NOTREACHED() << "Already watching an object"; 73 DCHECK(ThreadTaskRunnerHandle::IsSet());
83 return false;
84 }
85 74
86 origin_loop_ = MessageLoop::current(); 75 task_runner_ = ThreadTaskRunnerHandle::Get();
87 if (!origin_loop_)
88 return false;
89 76
90 run_once_ = execute_only_once; 77 run_once_ = execute_only_once;
91 78
92 // Since our job is to just notice when an object is signaled and report the 79 // Since our job is to just notice when an object is signaled and report the
93 // result back to this thread, we can just run on a Windows wait thread. 80 // result back to this thread, we can just run on a Windows wait thread.
94 DWORD wait_flags = WT_EXECUTEINWAITTHREAD; 81 DWORD wait_flags = WT_EXECUTEINWAITTHREAD;
95 if (run_once_) 82 if (run_once_)
96 wait_flags |= WT_EXECUTEONLYONCE; 83 wait_flags |= WT_EXECUTEONLYONCE;
97 84
98 // DoneWaiting can be synchronously called from RegisterWaitForSingleObject, 85 // DoneWaiting can be synchronously called from RegisterWaitForSingleObject,
99 // so set up all state now. 86 // so set up all state now.
100 callback_ = base::Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(), 87 callback_ =
101 delegate); 88 Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(), delegate);
102 object_ = object; 89 object_ = object;
103 90
104 if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting, 91 if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting,
105 this, INFINITE, wait_flags)) { 92 this, INFINITE, wait_flags)) {
106 DPLOG(FATAL) << "RegisterWaitForSingleObject failed"; 93 DPLOG(FATAL) << "RegisterWaitForSingleObject failed";
107 object_ = NULL; 94 Reset();
108 wait_object_ = NULL;
109 return false; 95 return false;
110 } 96 }
111 97
112 // We need to know if the current message loop is going away so we can
113 // prevent the wait thread from trying to access a dead message loop.
114 origin_loop_->AddDestructionObserver(this);
115 return true; 98 return true;
116 } 99 }
117 100
118 void ObjectWatcher::Signal(Delegate* delegate) { 101 void ObjectWatcher::Signal(Delegate* delegate) {
119 // Signaling the delegate may result in our destruction or a nested call to 102 // Signaling the delegate may result in our destruction or a nested call to
120 // StartWatching(). As a result, we save any state we need and clear previous 103 // StartWatching(). As a result, we save any state we need and clear previous
121 // watcher state before signaling the delegate. 104 // watcher state before signaling the delegate.
122 HANDLE object = object_; 105 HANDLE object = object_;
123 if (run_once_) 106 if (run_once_)
124 StopWatching(); 107 StopWatching();
125 delegate->OnObjectSignaled(object); 108 delegate->OnObjectSignaled(object);
126 } 109 }
127 110
128 void ObjectWatcher::WillDestroyCurrentMessageLoop() { 111 void ObjectWatcher::Reset() {
129 // Need to shutdown the watch so that we don't try to access the MessageLoop 112 callback_.Reset();
130 // after this point. 113 object_ = nullptr;
131 StopWatching(); 114 wait_object_ = nullptr;
115 task_runner_ = nullptr;
116 run_once_ = true;
117 weak_factory_.InvalidateWeakPtrs();
132 } 118 }
133 119
134 } // namespace win 120 } // namespace win
135 } // namespace base 121 } // namespace base
OLDNEW
« no previous file with comments | « base/win/object_watcher.h ('k') | chrome/common/service_process_util_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698