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

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

Issue 419773002: Take extra lock in base::WaitableEvent::WaitMany. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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) 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 <algorithm> 5 #include <algorithm>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/synchronization/waitable_event.h" 9 #include "base/synchronization/waitable_event.h"
10 #include "base/synchronization/condition_variable.h" 10 #include "base/synchronization/condition_variable.h"
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 272
273 sw.cv()->Wait(); 273 sw.cv()->Wait();
274 } 274 }
275 sw.lock()->Release(); 275 sw.lock()->Release();
276 276
277 // The address of the WaitableEvent which fired is stored in the SyncWaiter. 277 // The address of the WaitableEvent which fired is stored in the SyncWaiter.
278 WaitableEvent *const signaled_event = sw.signaling_event(); 278 WaitableEvent *const signaled_event = sw.signaling_event();
279 // This will store the index of the raw_waitables which fired. 279 // This will store the index of the raw_waitables which fired.
280 size_t signaled_index = 0; 280 size_t signaled_index = 0;
281 281
282 // Take the locks of each WaitableEvent in turn (except the signaled one) and 282 // Take the locks of each WaitableEvent in turn and
283 // remove our SyncWaiter from the wait-list 283 // remove our SyncWaiter from the wait-list
284 for (size_t i = 0; i < count; ++i) { 284 for (size_t i = 0; i < count; ++i) {
285 if (raw_waitables[i] != signaled_event) { 285 if (raw_waitables[i] != signaled_event) {
286 raw_waitables[i]->kernel_->lock_.Acquire(); 286 raw_waitables[i]->kernel_->lock_.Acquire();
287 // There's no possible ABA issue with the address of the SyncWaiter here 287 // There's no possible ABA issue with the address of the SyncWaiter here
288 // because it lives on the stack. Thus the tag value is just the pointer 288 // because it lives on the stack. Thus the tag value is just the pointer
289 // value again. 289 // value again.
290 raw_waitables[i]->kernel_->Dequeue(&sw, &sw); 290 raw_waitables[i]->kernel_->Dequeue(&sw, &sw);
291 raw_waitables[i]->kernel_->lock_.Release(); 291 raw_waitables[i]->kernel_->lock_.Release();
292 } else { 292 } else {
293 // We acquire and release the lock in order to ensure that the
agl 2014/07/25 17:32:46 It doesn't seem reasonable that WaitMany has this
yhirano 2014/07/29 06:48:11 TimedWait has the property because it acquires the
agl 2014/07/29 21:39:49 Ah, you have found a bug in the code! TimedWait ca
yhirano 2014/07/30 11:43:45 Hmm... I can easily find multiple code relying on
294 // corresponding |Signal| is done at this point.
295 raw_waitables[i]->kernel_->lock_.Acquire();
296 raw_waitables[i]->kernel_->lock_.Release();
297
293 signaled_index = i; 298 signaled_index = i;
294 } 299 }
295 } 300 }
296 301
297 return signaled_index; 302 return signaled_index;
298 } 303 }
299 304
300 // ----------------------------------------------------------------------------- 305 // -----------------------------------------------------------------------------
301 // If return value == 0: 306 // If return value == 0:
302 // The locks of the WaitableEvents have been taken in order and the Waiter has 307 // The locks of the WaitableEvents have been taken in order and the Waiter has
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 return true; 403 return true;
399 } 404 }
400 } 405 }
401 406
402 return false; 407 return false;
403 } 408 }
404 409
405 // ----------------------------------------------------------------------------- 410 // -----------------------------------------------------------------------------
406 411
407 } // namespace base 412 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698