OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chromecast/media/cma/ipc/media_message_fifo.h" | 5 #include "chromecast/media/cma/ipc/media_message_fifo.h" |
6 | 6 |
7 #include "base/atomicops.h" | 7 #include "base/atomicops.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 rd_offset_ = reinterpret_cast<AtomicSize*>(&(desc->rd_offset)); | 116 rd_offset_ = reinterpret_cast<AtomicSize*>(&(desc->rd_offset)); |
117 wr_offset_ = reinterpret_cast<AtomicSize*>(&(desc->wr_offset)); | 117 wr_offset_ = reinterpret_cast<AtomicSize*>(&(desc->wr_offset)); |
118 | 118 |
119 size_t max_size = mem_->size() - | 119 size_t max_size = mem_->size() - |
120 (static_cast<char*>(base_) - static_cast<char*>(mem_->data())); | 120 (static_cast<char*>(base_) - static_cast<char*>(mem_->data())); |
121 if (init) { | 121 if (init) { |
122 size_ = max_size; | 122 size_ = max_size; |
123 desc->size = size_; | 123 desc->size = size_; |
124 internal_rd_offset_ = 0; | 124 internal_rd_offset_ = 0; |
125 internal_wr_offset_ = 0; | 125 internal_wr_offset_ = 0; |
126 base::subtle::Acquire_Store(rd_offset_, 0); | 126 base::subtle::Release_Store(rd_offset_, 0); |
127 base::subtle::Acquire_Store(wr_offset_, 0); | 127 base::subtle::Release_Store(wr_offset_, 0); |
128 } else { | 128 } else { |
129 size_ = desc->size; | 129 size_ = desc->size; |
130 CHECK_LE(size_, max_size); | 130 CHECK_LE(size_, max_size); |
131 internal_rd_offset_ = current_rd_offset(); | 131 internal_rd_offset_ = current_rd_offset(); |
132 internal_wr_offset_ = current_wr_offset(); | 132 internal_wr_offset_ = current_wr_offset(); |
133 } | 133 } |
134 CMALOG(kLogControl) | 134 CMALOG(kLogControl) |
135 << "MediaMessageFifo:" << " init=" << init << " size=" << size_; | 135 << "MediaMessageFifo:" << " init=" << init << " size=" << size_; |
136 CHECK_GT(size_, 0) << size_; | 136 CHECK_GT(size_, 0) << size_; |
137 | 137 |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 size_t wr_offset = base::subtle::Acquire_Load(wr_offset_); | 363 size_t wr_offset = base::subtle::Acquire_Load(wr_offset_); |
364 CHECK_LT(wr_offset, size_); | 364 CHECK_LT(wr_offset, size_); |
365 return wr_offset; | 365 return wr_offset; |
366 } | 366 } |
367 | 367 |
368 void MediaMessageFifo::CommitRead(size_t new_rd_offset) { | 368 void MediaMessageFifo::CommitRead(size_t new_rd_offset) { |
369 // Add a memory fence to ensure the message content is completely read | 369 // Add a memory fence to ensure the message content is completely read |
370 // before updating the read offset. | 370 // before updating the read offset. |
371 base::subtle::Release_Store(rd_offset_, new_rd_offset); | 371 base::subtle::Release_Store(rd_offset_, new_rd_offset); |
372 | 372 |
373 // Make sure the read pointer has been updated before sending a notification. | 373 // Since rd_offset_ is updated by a release_store above, any thread that |
| 374 // does acquire_load is guaranteed to see the new rd_offset_ set above. |
| 375 // So it is safe to send the notification. |
374 if (!read_event_cb_.is_null()) { | 376 if (!read_event_cb_.is_null()) { |
375 base::subtle::MemoryBarrier(); | |
376 read_event_cb_.Run(); | 377 read_event_cb_.Run(); |
377 } | 378 } |
378 } | 379 } |
379 | 380 |
380 void MediaMessageFifo::CommitWrite(size_t new_wr_offset) { | 381 void MediaMessageFifo::CommitWrite(size_t new_wr_offset) { |
381 // Add a memory fence to ensure the message content is written | 382 // Add a memory fence to ensure the message content is written |
382 // before updating the write offset. | 383 // before updating the write offset. |
383 base::subtle::Release_Store(wr_offset_, new_wr_offset); | 384 base::subtle::Release_Store(wr_offset_, new_wr_offset); |
384 | 385 |
385 // Make sure the write pointer has been updated before sending a notification. | 386 // Since wr_offset_ is updated by a release_store above, any thread that |
| 387 // does acquire_load is guaranteed to see the new wr_offset_ set above. |
| 388 // So it is safe to send the notification. |
386 if (!write_event_cb_.is_null()) { | 389 if (!write_event_cb_.is_null()) { |
387 base::subtle::MemoryBarrier(); | |
388 write_event_cb_.Run(); | 390 write_event_cb_.Run(); |
389 } | 391 } |
390 } | 392 } |
391 | 393 |
392 void MediaMessageFifo::CommitInternalRead(size_t new_rd_offset) { | 394 void MediaMessageFifo::CommitInternalRead(size_t new_rd_offset) { |
393 internal_rd_offset_ = new_rd_offset; | 395 internal_rd_offset_ = new_rd_offset; |
394 } | 396 } |
395 | 397 |
396 void MediaMessageFifo::CommitInternalWrite(size_t new_wr_offset) { | 398 void MediaMessageFifo::CommitInternalWrite(size_t new_wr_offset) { |
397 internal_wr_offset_ = new_wr_offset; | 399 internal_wr_offset_ = new_wr_offset; |
398 } | 400 } |
399 | 401 |
400 } // namespace media | 402 } // namespace media |
401 } // namespace chromecast | 403 } // namespace chromecast |
OLD | NEW |