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

Side by Side Diff: base/synchronization/waitable_event_watcher_posix.cc

Issue 12087120: Revert 179987 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
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/synchronization/waitable_event_watcher.h" 5 #include "base/synchronization/waitable_event_watcher.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 base::Closure callback_; 90 base::Closure callback_;
91 scoped_refptr<Flag> flag_; 91 scoped_refptr<Flag> flag_;
92 }; 92 };
93 93
94 // ----------------------------------------------------------------------------- 94 // -----------------------------------------------------------------------------
95 // For async waits we need to make a callback in a MessageLoop thread. We do 95 // For async waits we need to make a callback in a MessageLoop thread. We do
96 // this by posting a callback, which calls the delegate and keeps track of when 96 // this by posting a callback, which calls the delegate and keeps track of when
97 // the event is canceled. 97 // the event is canceled.
98 // ----------------------------------------------------------------------------- 98 // -----------------------------------------------------------------------------
99 void AsyncCallbackHelper(Flag* flag, 99 void AsyncCallbackHelper(Flag* flag,
100 const WaitableEventWatcher::EventCallback& callback, 100 WaitableEventWatcher::Delegate* delegate,
101 WaitableEvent* event) { 101 WaitableEvent* event) {
102 // Runs in MessageLoop thread. 102 // Runs in MessageLoop thread.
103 if (!flag->value()) { 103 if (!flag->value()) {
104 // This is to let the WaitableEventWatcher know that the event has occured 104 // This is to let the WaitableEventWatcher know that the event has occured
105 // because it needs to be able to return NULL from GetWatchedObject 105 // because it needs to be able to return NULL from GetWatchedObject
106 flag->Set(); 106 flag->Set();
107 callback.Run(event); 107 delegate->OnWaitableEventSignaled(event);
108 } 108 }
109 } 109 }
110 110
111 WaitableEventWatcher::WaitableEventWatcher() 111 WaitableEventWatcher::WaitableEventWatcher()
112 : message_loop_(NULL), 112 : message_loop_(NULL),
113 cancel_flag_(NULL), 113 cancel_flag_(NULL),
114 waiter_(NULL), 114 waiter_(NULL),
115 event_(NULL) { 115 event_(NULL),
116 delegate_(NULL) {
116 } 117 }
117 118
118 WaitableEventWatcher::~WaitableEventWatcher() { 119 WaitableEventWatcher::~WaitableEventWatcher() {
119 StopWatching(); 120 StopWatching();
120 } 121 }
121 122
122 // ----------------------------------------------------------------------------- 123 // -----------------------------------------------------------------------------
123 // The Handle is how the user cancels a wait. After deleting the Handle we 124 // The Handle is how the user cancels a wait. After deleting the Handle we
124 // insure that the delegate cannot be called. 125 // insure that the delegate cannot be called.
125 // ----------------------------------------------------------------------------- 126 // -----------------------------------------------------------------------------
126 bool WaitableEventWatcher::StartWatching( 127 bool WaitableEventWatcher::StartWatching
127 WaitableEvent* event, 128 (WaitableEvent* event, WaitableEventWatcher::Delegate* delegate) {
128 const EventCallback& callback) {
129 MessageLoop *const current_ml = MessageLoop::current(); 129 MessageLoop *const current_ml = MessageLoop::current();
130 DCHECK(current_ml) << "Cannot create WaitableEventWatcher without a " 130 DCHECK(current_ml) << "Cannot create WaitableEventWatcher without a "
131 "current MessageLoop"; 131 "current MessageLoop";
132 132
133 // A user may call StartWatching from within the callback function. In this 133 // A user may call StartWatching from within the callback function. In this
134 // case, we won't know that we have finished watching, expect that the Flag 134 // case, we won't know that we have finished watching, expect that the Flag
135 // will have been set in AsyncCallbackHelper(). 135 // will have been set in AsyncCallbackHelper().
136 if (cancel_flag_.get() && cancel_flag_->value()) { 136 if (cancel_flag_.get() && cancel_flag_->value()) {
137 if (message_loop_) { 137 if (message_loop_) {
138 message_loop_->RemoveDestructionObserver(this); 138 message_loop_->RemoveDestructionObserver(this);
139 message_loop_ = NULL; 139 message_loop_ = NULL;
140 } 140 }
141 141
142 cancel_flag_ = NULL; 142 cancel_flag_ = NULL;
143 } 143 }
144 144
145 DCHECK(!cancel_flag_.get()) << "StartWatching called while still watching"; 145 DCHECK(!cancel_flag_.get()) << "StartWatching called while still watching";
146 146
147 cancel_flag_ = new Flag; 147 cancel_flag_ = new Flag;
148 callback_ = callback; 148 callback_ = base::Bind(&AsyncCallbackHelper, cancel_flag_, delegate, event);
149 internal_callback_ =
150 base::Bind(&AsyncCallbackHelper, cancel_flag_, callback_, event);
151 WaitableEvent::WaitableEventKernel* kernel = event->kernel_.get(); 149 WaitableEvent::WaitableEventKernel* kernel = event->kernel_.get();
152 150
153 AutoLock locked(kernel->lock_); 151 AutoLock locked(kernel->lock_);
154 152
153 delegate_ = delegate;
155 event_ = event; 154 event_ = event;
156 155
157 if (kernel->signaled_) { 156 if (kernel->signaled_) {
158 if (!kernel->manual_reset_) 157 if (!kernel->manual_reset_)
159 kernel->signaled_ = false; 158 kernel->signaled_ = false;
160 159
161 // No hairpinning - we can't call the delegate directly here. We have to 160 // No hairpinning - we can't call the delegate directly here. We have to
162 // enqueue a task on the MessageLoop as normal. 161 // enqueue a task on the MessageLoop as normal.
163 current_ml->PostTask(FROM_HERE, internal_callback_); 162 current_ml->PostTask(FROM_HERE, callback_);
164 return true; 163 return true;
165 } 164 }
166 165
167 message_loop_ = current_ml; 166 message_loop_ = current_ml;
168 current_ml->AddDestructionObserver(this); 167 current_ml->AddDestructionObserver(this);
169 168
170 kernel_ = kernel; 169 kernel_ = kernel;
171 waiter_ = new AsyncWaiter(current_ml, internal_callback_, cancel_flag_); 170 waiter_ = new AsyncWaiter(current_ml, callback_, cancel_flag_);
172 event->Enqueue(waiter_); 171 event->Enqueue(waiter_);
173 172
174 return true; 173 return true;
175 } 174 }
176 175
177 void WaitableEventWatcher::StopWatching() { 176 void WaitableEventWatcher::StopWatching() {
178 callback_.Reset(); 177 delegate_ = NULL;
179 178
180 if (message_loop_) { 179 if (message_loop_) {
181 message_loop_->RemoveDestructionObserver(this); 180 message_loop_->RemoveDestructionObserver(this);
182 message_loop_ = NULL; 181 message_loop_ = NULL;
183 } 182 }
184 183
185 if (!cancel_flag_.get()) // if not currently watching... 184 if (!cancel_flag_.get()) // if not currently watching...
186 return; 185 return;
187 186
188 if (cancel_flag_->value()) { 187 if (cancel_flag_->value()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 // a tag which is good for the lifetime of this handle: the Flag. Since we 220 // a tag which is good for the lifetime of this handle: the Flag. Since we
222 // have a reference to the Flag, its memory cannot be reused while this object 221 // have a reference to the Flag, its memory cannot be reused while this object
223 // still exists. So if we find a waiter with the correct pointer value, and 222 // still exists. So if we find a waiter with the correct pointer value, and
224 // which shares a Flag pointer, we have a real match. 223 // which shares a Flag pointer, we have a real match.
225 if (kernel_->Dequeue(waiter_, cancel_flag_.get())) { 224 if (kernel_->Dequeue(waiter_, cancel_flag_.get())) {
226 // Case 2: the waiter hasn't been signaled yet; it was still on the wait 225 // Case 2: the waiter hasn't been signaled yet; it was still on the wait
227 // list. We've removed it, thus we can delete it and the task (which cannot 226 // list. We've removed it, thus we can delete it and the task (which cannot
228 // have been enqueued with the MessageLoop because the waiter was never 227 // have been enqueued with the MessageLoop because the waiter was never
229 // signaled) 228 // signaled)
230 delete waiter_; 229 delete waiter_;
231 internal_callback_.Reset(); 230 callback_.Reset();
232 cancel_flag_ = NULL; 231 cancel_flag_ = NULL;
233 return; 232 return;
234 } 233 }
235 234
236 // Case 3: the waiter isn't on the wait-list, thus it was signaled. It may 235 // Case 3: the waiter isn't on the wait-list, thus it was signaled. It may
237 // not have run yet, so we set the flag to tell it not to bother enqueuing the 236 // not have run yet, so we set the flag to tell it not to bother enqueuing the
238 // task on the MessageLoop, but to delete it instead. The Waiter deletes 237 // task on the MessageLoop, but to delete it instead. The Waiter deletes
239 // itself once run. 238 // itself once run.
240 cancel_flag_->Set(); 239 cancel_flag_->Set();
241 cancel_flag_ = NULL; 240 cancel_flag_ = NULL;
(...skipping 20 matching lines...) Expand all
262 // ----------------------------------------------------------------------------- 261 // -----------------------------------------------------------------------------
263 // This is called when the MessageLoop which the callback will be run it is 262 // This is called when the MessageLoop which the callback will be run it is
264 // deleted. We need to cancel the callback as if we had been deleted, but we 263 // deleted. We need to cancel the callback as if we had been deleted, but we
265 // will still be deleted at some point in the future. 264 // will still be deleted at some point in the future.
266 // ----------------------------------------------------------------------------- 265 // -----------------------------------------------------------------------------
267 void WaitableEventWatcher::WillDestroyCurrentMessageLoop() { 266 void WaitableEventWatcher::WillDestroyCurrentMessageLoop() {
268 StopWatching(); 267 StopWatching();
269 } 268 }
270 269
271 } // namespace base 270 } // namespace base
OLDNEW
« no previous file with comments | « base/synchronization/waitable_event_watcher.h ('k') | base/synchronization/waitable_event_watcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698