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

Side by Side Diff: content/child/shared_memory_data_consumer_handle.cc

Issue 1234213002: Fix data races on |SharedMemoryDataConsumerHandle::Context::notification_task_runner_| (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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 | « 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 "content/child/shared_memory_data_consumer_handle.h" 5 #include "content/child/shared_memory_data_consumer_handle.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <deque> 8 #include <deque>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 } 153 }
154 void set_is_two_phase_read_in_progress(bool b) { 154 void set_is_two_phase_read_in_progress(bool b) {
155 is_two_phase_read_in_progress_ = b; 155 is_two_phase_read_in_progress_ = b;
156 } 156 }
157 base::Lock& lock() { return lock_; } 157 base::Lock& lock() { return lock_; }
158 158
159 private: 159 private:
160 void NotifyInternal(bool repost) { 160 void NotifyInternal(bool repost) {
161 // Note that this function is not protected by |lock_|. 161 // Note that this function is not protected by |lock_|.
162 162
163 auto runner = notification_task_runner_; 163 scoped_refptr<base::SingleThreadTaskRunner> runner;
164 {
165 base::AutoLock lock(lock_);
166 runner = notification_task_runner_;
167 }
164 if (!runner) 168 if (!runner)
165 return; 169 return;
166 170
167 if (runner->BelongsToCurrentThread()) { 171 if (runner->BelongsToCurrentThread()) {
168 // It is safe to access member variables without lock because |client_| 172 // It is safe to access member variables without lock because |client_|
169 // is bound to the current thread. 173 // is bound to the current thread.
170 if (client_) 174 if (client_)
171 client_->didGetReadable(); 175 client_->didGetReadable();
172 return; 176 return;
173 } 177 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 270
267 if (needs_notification) { 271 if (needs_notification) {
268 // We CAN issue the notification synchronously if the associated reader 272 // We CAN issue the notification synchronously if the associated reader
269 // lives in this thread, because this function cannot be called in the 273 // lives in this thread, because this function cannot be called in the
270 // client's callback. 274 // client's callback.
271 context_->Notify(); 275 context_->Notify();
272 } 276 }
273 } 277 }
274 278
275 void SharedMemoryDataConsumerHandle::Writer::Close() { 279 void SharedMemoryDataConsumerHandle::Writer::Close() {
276 bool needs_notification = false; 280 base::AutoLock lock(context_->lock());
277 281 if (context_->result() == Ok) {
278 { 282 context_->set_result(Done);
279 base::AutoLock lock(context_->lock()); 283 context_->ResetOnReaderDetached();
280 if (context_->result() == Ok) { 284 if (context_->IsEmpty()) {
281 context_->set_result(Done); 285 // We cannot issue the notification synchronously because this function
282 context_->ResetOnReaderDetached(); 286 // can be called in the client's callback.
283 needs_notification = context_->IsEmpty(); 287 context_->PostNotify();
kinuko 2015/07/16 03:28:44 If some methods of Context are assumed to be calle
hiroshige 2015/07/16 05:35:58 Added comments/assertions in Patch Set 4.
284 } 288 }
285 } 289 }
286 if (needs_notification) {
287 // We cannot issue the notification synchronously because this function can
288 // be called in the client's callback.
289 context_->PostNotify();
290 }
291 } 290 }
292 291
293 void SharedMemoryDataConsumerHandle::Writer::Fail() { 292 void SharedMemoryDataConsumerHandle::Writer::Fail() {
294 bool needs_notification = false; 293 base::AutoLock lock(context_->lock());
295 { 294 if (context_->result() == Ok) {
296 base::AutoLock lock(context_->lock()); 295 // TODO(yhirano): Use an appropriate error code other than
297 if (context_->result() == Ok) { 296 // UnexpectedError.
298 // TODO(yhirano): Use an appropriate error code other than 297 context_->set_result(UnexpectedError);
299 // UnexpectedError.
300 context_->set_result(UnexpectedError);
301 298
302 if (context_->is_two_phase_read_in_progress()) { 299 if (context_->is_two_phase_read_in_progress()) {
303 // If we are in two-phase read session, we cannot discard the data. We 300 // If we are in two-phase read session, we cannot discard the data. We
304 // will clear the queue at the end of the session. 301 // will clear the queue at the end of the session.
305 } else { 302 } else {
306 context_->ClearQueue(); 303 context_->ClearQueue();
307 } 304 }
308 305
309 context_->ResetOnReaderDetached(); 306 context_->ResetOnReaderDetached();
310 needs_notification = true;
311 }
312 }
313 if (needs_notification) {
314 // We cannot issue the notification synchronously because this function can 307 // We cannot issue the notification synchronously because this function can
315 // be called in the client's callback. 308 // be called in the client's callback.
316 context_->PostNotify(); 309 context_->PostNotify();
317 } 310 }
318 } 311 }
319 312
320 SharedMemoryDataConsumerHandle::ReaderImpl::ReaderImpl( 313 SharedMemoryDataConsumerHandle::ReaderImpl::ReaderImpl(
321 scoped_refptr<Context> context, 314 scoped_refptr<Context> context,
322 Client* client) 315 Client* client)
323 : context_(context) { 316 : context_(context) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 SharedMemoryDataConsumerHandle::ReaderImpl* 431 SharedMemoryDataConsumerHandle::ReaderImpl*
439 SharedMemoryDataConsumerHandle::obtainReaderInternal(Client* client) { 432 SharedMemoryDataConsumerHandle::obtainReaderInternal(Client* client) {
440 return new ReaderImpl(context_, client); 433 return new ReaderImpl(context_, client);
441 } 434 }
442 435
443 const char* SharedMemoryDataConsumerHandle::debugName() const { 436 const char* SharedMemoryDataConsumerHandle::debugName() const {
444 return "SharedMemoryDataConsumerHandle"; 437 return "SharedMemoryDataConsumerHandle";
445 } 438 }
446 439
447 } // namespace content 440 } // namespace content
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