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

Side by Side Diff: mojo/edk/system/wait_set_dispatcher.cc

Issue 1708953002: Fix a logical race when adding an awakable to a wait set. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
« 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "mojo/edk/system/wait_set_dispatcher.h" 5 #include "mojo/edk/system/wait_set_dispatcher.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <utility> 10 #include <utility>
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 if (!awoken_queue_.empty() || !processed_dispatchers_.empty()) 239 if (!awoken_queue_.empty() || !processed_dispatchers_.empty())
240 rv.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE; 240 rv.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE;
241 return rv; 241 return rv;
242 } 242 }
243 243
244 MojoResult WaitSetDispatcher::AddAwakable(Awakable* awakable, 244 MojoResult WaitSetDispatcher::AddAwakable(Awakable* awakable,
245 MojoHandleSignals signals, 245 MojoHandleSignals signals,
246 uintptr_t context, 246 uintptr_t context,
247 HandleSignalsState* signals_state) { 247 HandleSignalsState* signals_state) {
248 base::AutoLock lock(lock_); 248 base::AutoLock lock(lock_);
249 // |awakable_lock_| is acquired here instead of immediately before adding to
250 // |awakable_list_| because we need to check the signals state and add to
251 // |awakable_list_| as an atomic operation. If the pair isn't atomic, it is
252 // possible for the signals state to change after it is checked, but before
253 // the awakable is added. In that case, the added awakable won't be signalled.
254 base::AutoLock awakable_locker(awakable_lock_);
249 HandleSignalsState state(GetHandleSignalsStateNoLock()); 255 HandleSignalsState state(GetHandleSignalsStateNoLock());
250 if (state.satisfies(signals)) { 256 if (state.satisfies(signals)) {
251 if (signals_state) 257 if (signals_state)
252 *signals_state = state; 258 *signals_state = state;
253 return MOJO_RESULT_ALREADY_EXISTS; 259 return MOJO_RESULT_ALREADY_EXISTS;
254 } 260 }
255 if (!state.can_satisfy(signals)) { 261 if (!state.can_satisfy(signals)) {
256 if (signals_state) 262 if (signals_state)
257 *signals_state = state; 263 *signals_state = state;
258 return MOJO_RESULT_FAILED_PRECONDITION; 264 return MOJO_RESULT_FAILED_PRECONDITION;
259 } 265 }
260 266
261 base::AutoLock locker(awakable_lock_);
262 awakable_list_.Add(awakable, signals, context); 267 awakable_list_.Add(awakable, signals, context);
263 return MOJO_RESULT_OK; 268 return MOJO_RESULT_OK;
264 } 269 }
265 270
266 void WaitSetDispatcher::RemoveAwakable(Awakable* awakable, 271 void WaitSetDispatcher::RemoveAwakable(Awakable* awakable,
267 HandleSignalsState* signals_state) { 272 HandleSignalsState* signals_state) {
268 { 273 {
269 base::AutoLock locker(awakable_lock_); 274 base::AutoLock locker(awakable_lock_);
270 awakable_list_.Remove(awakable); 275 awakable_list_.Remove(awakable);
271 } 276 }
(...skipping 24 matching lines...) Expand all
296 301
297 base::AutoLock locker(awakable_lock_); 302 base::AutoLock locker(awakable_lock_);
298 HandleSignalsState signals_state; 303 HandleSignalsState signals_state;
299 signals_state.satisfiable_signals = MOJO_HANDLE_SIGNAL_READABLE; 304 signals_state.satisfiable_signals = MOJO_HANDLE_SIGNAL_READABLE;
300 signals_state.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE; 305 signals_state.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE;
301 awakable_list_.AwakeForStateChange(signals_state); 306 awakable_list_.AwakeForStateChange(signals_state);
302 } 307 }
303 308
304 } // namespace edk 309 } // namespace edk
305 } // namespace mojo 310 } // namespace mojo
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