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

Side by Side Diff: base/waitable_event_watcher_posix.cc

Issue 18298: Mac/Linux test fixes: hopefully this will fix some flakey tests (Closed)
Patch Set: Created 11 years, 11 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/waitable_event_posix.cc ('k') | no next file » | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/waitable_event_watcher.h" 5 #include "base/waitable_event_watcher.h"
6 6
7 #include "base/condition_variable.h" 7 #include "base/condition_variable.h"
8 #include "base/lock.h" 8 #include "base/lock.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/waitable_event.h" 10 #include "base/waitable_event.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 // We can always return true because an AsyncWaiter is never in two 73 // We can always return true because an AsyncWaiter is never in two
74 // different wait-lists at the same time. 74 // different wait-lists at the same time.
75 return true; 75 return true;
76 } 76 }
77 77
78 // See StopWatching for discussion 78 // See StopWatching for discussion
79 bool Compare(void* tag) { 79 bool Compare(void* tag) {
80 return tag == flag_.get(); 80 return tag == flag_.get();
81 } 81 }
82 82
83 private:
83 MessageLoop *const message_loop_; 84 MessageLoop *const message_loop_;
84 Task *const cb_task_; 85 Task *const cb_task_;
85 scoped_refptr<Flag> flag_; 86 scoped_refptr<Flag> flag_;
86 }; 87 };
87 88
88 // ----------------------------------------------------------------------------- 89 // -----------------------------------------------------------------------------
89 // For async waits we need to make a callback in a MessageLoop thread. We do 90 // For async waits we need to make a callback in a MessageLoop thread. We do
90 // this by posting this task, which calls the delegate and keeps track of when 91 // this by posting this task, which calls the delegate and keeps track of when
91 // the event is canceled. 92 // the event is canceled.
92 // ----------------------------------------------------------------------------- 93 // -----------------------------------------------------------------------------
93 class AsyncCallbackTask : public Task { 94 class AsyncCallbackTask : public Task {
94 public: 95 public:
95 AsyncCallbackTask(Flag* flag, WaitableEventWatcher::Delegate* delegate, 96 AsyncCallbackTask(Flag* flag, WaitableEventWatcher::Delegate* delegate,
96 WaitableEvent* event) 97 WaitableEvent* event)
97 : flag_(flag), 98 : flag_(flag),
98 delegate_(delegate), 99 delegate_(delegate),
99 event_(event) { 100 event_(event) {
100 } 101 }
101 102
102 void Run() { 103 void Run() {
103 // Runs in MessageLoop thread. 104 // Runs in MessageLoop thread.
104 if (!flag_->value()) 105 if (!flag_->value()) {
106 // This is to let the WaitableEventWatcher know that the event has occured
107 // because it needs to be able to return NULL from GetWatchedObject
108 flag_->Set();
105 delegate_->OnWaitableEventSignaled(event_); 109 delegate_->OnWaitableEventSignaled(event_);
106 110 }
107 // This is to let the WaitableEventWatcher know that the event has occured
108 // because it needs to be able to return NULL from GetWatchedEvent
109 flag_->Set();
110 111
111 // We are deleted by the MessageLoop 112 // We are deleted by the MessageLoop
112 } 113 }
113 114
114 private: 115 private:
115 scoped_refptr<Flag> flag_; 116 scoped_refptr<Flag> flag_;
116 WaitableEventWatcher::Delegate *const delegate_; 117 WaitableEventWatcher::Delegate *const delegate_;
117 WaitableEvent *const event_; 118 WaitableEvent *const event_;
118 }; 119 };
119 120
(...skipping 11 matching lines...) Expand all
131 // ----------------------------------------------------------------------------- 132 // -----------------------------------------------------------------------------
132 // The Handle is how the user cancels a wait. After deleting the Handle we 133 // The Handle is how the user cancels a wait. After deleting the Handle we
133 // insure that the delegate cannot be called. 134 // insure that the delegate cannot be called.
134 // ----------------------------------------------------------------------------- 135 // -----------------------------------------------------------------------------
135 bool WaitableEventWatcher::StartWatching 136 bool WaitableEventWatcher::StartWatching
136 (WaitableEvent* event, WaitableEventWatcher::Delegate* delegate) { 137 (WaitableEvent* event, WaitableEventWatcher::Delegate* delegate) {
137 MessageLoop *const current_ml = MessageLoop::current(); 138 MessageLoop *const current_ml = MessageLoop::current();
138 DCHECK(current_ml) << "Cannot create WaitableEventWatcher without a " 139 DCHECK(current_ml) << "Cannot create WaitableEventWatcher without a "
139 "current MessageLoop"; 140 "current MessageLoop";
140 141
142 // A user may call StartWatching from within the callback function. In this
143 // case, we won't know that we have finished watching, expect that the Flag
144 // will have been set in AsyncCallbackTask::Run()
145 if (cancel_flag_.get() && cancel_flag_->value()) {
146 if (message_loop_) {
147 message_loop_->RemoveDestructionObserver(this);
148 message_loop_ = NULL;
149 }
150
151 cancel_flag_ = NULL;
152 }
153
141 DCHECK(!cancel_flag_.get()) << "StartWatching called while still watching"; 154 DCHECK(!cancel_flag_.get()) << "StartWatching called while still watching";
142 155
143 cancel_flag_ = new Flag; 156 cancel_flag_ = new Flag;
144 callback_task_ = new AsyncCallbackTask(cancel_flag_, delegate, event); 157 callback_task_ = new AsyncCallbackTask(cancel_flag_, delegate, event);
145 158
146 AutoLock locked(event->lock_); 159 AutoLock locked(event->lock_);
147 160
148 if (event->signaled_) { 161 if (event->signaled_) {
149 if (!event->manual_reset_) 162 if (!event->manual_reset_)
150 event->signaled_ = false; 163 event->signaled_ = false;
(...skipping 16 matching lines...) Expand all
167 180
168 void WaitableEventWatcher::StopWatching() { 181 void WaitableEventWatcher::StopWatching() {
169 if (message_loop_) { 182 if (message_loop_) {
170 message_loop_->RemoveDestructionObserver(this); 183 message_loop_->RemoveDestructionObserver(this);
171 message_loop_ = NULL; 184 message_loop_ = NULL;
172 } 185 }
173 186
174 if (!cancel_flag_.get()) // if not currently watching... 187 if (!cancel_flag_.get()) // if not currently watching...
175 return; 188 return;
176 189
190 if (cancel_flag_->value()) {
191 // In this case, the event has fired, but we haven't figured that out yet.
192 // The WaitableEvent may have been deleted too.
193 cancel_flag_ = NULL;
194 return;
195 }
196
177 if (!event_) { 197 if (!event_) {
178 // We have no WaitableEvent. This means that we never enqueued a Waiter on 198 // We have no WaitableEvent. This means that we never enqueued a Waiter on
179 // an event because the event was already signaled when StartWatching was 199 // an event because the event was already signaled when StartWatching was
180 // called. 200 // called.
181 // 201 //
182 // In this case, a task was enqueued on the MessageLoop and will run. 202 // In this case, a task was enqueued on the MessageLoop and will run.
183 // We set the flag in case the task hasn't yet run. The flag will stop the 203 // We set the flag in case the task hasn't yet run. The flag will stop the
184 // delegate getting called. If the task has run then we have the last 204 // delegate getting called. If the task has run then we have the last
185 // reference to the flag and it will be deleted immedately after. 205 // reference to the flag and it will be deleted immedately after.
186 cancel_flag_->Set(); 206 cancel_flag_->Set();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 // ----------------------------------------------------------------------------- 264 // -----------------------------------------------------------------------------
245 // This is called when the MessageLoop which the callback will be run it is 265 // This is called when the MessageLoop which the callback will be run it is
246 // deleted. We need to cancel the callback as if we had been deleted, but we 266 // deleted. We need to cancel the callback as if we had been deleted, but we
247 // will still be deleted at some point in the future. 267 // will still be deleted at some point in the future.
248 // ----------------------------------------------------------------------------- 268 // -----------------------------------------------------------------------------
249 void WaitableEventWatcher::WillDestroyCurrentMessageLoop() { 269 void WaitableEventWatcher::WillDestroyCurrentMessageLoop() {
250 StopWatching(); 270 StopWatching();
251 } 271 }
252 272
253 } // namespace base 273 } // namespace base
OLDNEW
« no previous file with comments | « base/waitable_event_posix.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698