7 #include "packager/media/file/io_cache.h"
13 #include "packager/base/logging.h"
14 #include "packager/base/stl_util.h"
16 namespace edash_packager {
19 using base::AutoUnlock;
23 IoCache::IoCache(uint64_t cache_size)
24 : cache_size_(cache_size),
25 read_event_(false, false),
26 write_event_(false, false),
29 circular_buffer_(cache_size + 1),
30 end_ptr_(&circular_buffer_[0] + cache_size + 1),
31 r_ptr_(vector_as_array(&circular_buffer_)),
32 w_ptr_(vector_as_array(&circular_buffer_)),
43 while (!closed_ && (BytesCachedInternal() == 0)) {
44 AutoUnlock unlock(lock_);
48 size = std::min(size, BytesCachedInternal());
49 uint64_t first_chunk_size(std::min(size, static_cast<uint64_t>(
51 memcpy(buffer, r_ptr_, first_chunk_size);
52 r_ptr_ += first_chunk_size;
53 DCHECK_GE(end_ptr_, r_ptr_);
54 if (r_ptr_ == end_ptr_)
55 r_ptr_ = &circular_buffer_[0];
56 uint64_t second_chunk_size(size - first_chunk_size);
57 if (second_chunk_size) {
58 memcpy(static_cast<uint8_t*>(buffer) + first_chunk_size, r_ptr_,
60 r_ptr_ += second_chunk_size;
61 DCHECK_GT(end_ptr_, r_ptr_);
70 const uint8_t* r_ptr(static_cast<const uint8_t*>(buffer));
71 uint64_t bytes_left(size);
74 while (!closed_ && (BytesFreeInternal() == 0)) {
75 AutoUnlock unlock(lock_);
81 uint64_t write_size(std::min(bytes_left, BytesFreeInternal()));
82 uint64_t first_chunk_size(std::min(write_size, static_cast<uint64_t>(
84 memcpy(w_ptr_, r_ptr, first_chunk_size);
85 w_ptr_ += first_chunk_size;
86 DCHECK_GE(end_ptr_, w_ptr_);
87 if (w_ptr_ == end_ptr_)
88 w_ptr_ = &circular_buffer_[0];
89 r_ptr += first_chunk_size;
90 uint64_t second_chunk_size(write_size - first_chunk_size);
91 if (second_chunk_size) {
92 memcpy(w_ptr_, r_ptr, second_chunk_size);
93 w_ptr_ += second_chunk_size;
94 DCHECK_GT(end_ptr_, w_ptr_);
95 r_ptr += second_chunk_size;
97 bytes_left -= write_size;
98 write_event_.Signal();
104 AutoLock lock(lock_);
105 r_ptr_ = w_ptr_ = vector_as_array(&circular_buffer_);
107 read_event_.Signal();
111 AutoLock lock(lock_);
113 read_event_.Signal();
114 write_event_.Signal();
118 AutoLock lock(lock_);
120 r_ptr_ = w_ptr_ = vector_as_array(&circular_buffer_);
123 write_event_.Reset();
127 AutoLock lock(lock_);
128 return BytesCachedInternal();
132 AutoLock lock(lock_);
133 return BytesFreeInternal();
136 uint64_t IoCache::BytesCachedInternal() {
137 return (r_ptr_ <= w_ptr_) ?
139 (end_ptr_ - r_ptr_) + (w_ptr_ - vector_as_array(&circular_buffer_));
142 uint64_t IoCache::BytesFreeInternal() {
143 return cache_size_ - BytesCachedInternal();
147 AutoLock lock(lock_);
148 while (!closed_ && BytesCachedInternal()) {
149 AutoUnlock unlock(lock_);