7 #include "packager/media/file/threaded_io_file.h"
9 #include "packager/base/bind.h"
10 #include "packager/base/bind_helpers.h"
11 #include "packager/base/threading/platform_thread.h"
12 #include "packager/media/base/closure_thread.h"
14 namespace edash_packager {
17 using base::subtle::NoBarrier_Load;
18 using base::subtle::NoBarrier_Store;
20 ThreadedIoFile::ThreadedIoFile(scoped_ptr<File, FileCloser> internal_file,
22 uint64_t io_cache_size,
23 uint64_t io_block_size)
24 : File(internal_file->file_name()),
25 internal_file_(internal_file.Pass()),
27 cache_(io_cache_size),
28 io_buffer_(io_block_size),
33 flush_complete_event_(false, false),
34 internal_file_error_(0){
35 DCHECK(internal_file_);
38 ThreadedIoFile::~ThreadedIoFile() {}
41 DCHECK(internal_file_);
43 if (!internal_file_->Open())
47 size_ = internal_file_->Size();
50 base::Bind(mode_ == kInputMode ?
51 &ThreadedIoFile::RunInInputMode :
52 &ThreadedIoFile::RunInOutputMode,
53 base::Unretained(
this))));
59 DCHECK(internal_file_);
62 if (mode_ == kOutputMode)
68 bool result = internal_file_.release()->Close();
74 DCHECK(internal_file_);
76 DCHECK_EQ(kInputMode, mode_);
81 if (NoBarrier_Load(&internal_file_error_))
82 return NoBarrier_Load(&internal_file_error_);
85 uint64_t bytes_read = cache_.
Read(buffer, length);
86 position_ += bytes_read;
92 DCHECK(internal_file_);
94 DCHECK_EQ(kOutputMode, mode_);
96 if (NoBarrier_Load(&internal_file_error_))
97 return NoBarrier_Load(&internal_file_error_);
99 uint64_t bytes_written = cache_.
Write(buffer, length);
100 position_ += bytes_written;
101 if (position_ > size_)
104 return bytes_written;
108 DCHECK(internal_file_);
115 DCHECK(internal_file_);
117 DCHECK_EQ(kOutputMode, mode_);
121 flush_complete_event_.Wait();
122 return internal_file_->Flush();
126 if (mode_ == kOutputMode) {
128 if (!
Flush())
return false;
129 if (!internal_file_->Seek(position))
return false;
135 bool result = internal_file_->Seek(position);
138 if (!internal_file_->Seek(position_) && (position != position_)) {
139 LOG(WARNING) <<
"Seek failed. ThreadedIoFile left in invalid state.";
145 base::Bind(&ThreadedIoFile::RunInInputMode,
146 base::Unretained(
this))));
148 if (!result)
return false;
150 position_ = position;
157 *position = position_;
161 void ThreadedIoFile::RunInInputMode() {
162 DCHECK(internal_file_);
164 DCHECK_EQ(kInputMode, mode_);
167 int64_t read_result = internal_file_->Read(&io_buffer_[0],
169 if (read_result <= 0) {
170 NoBarrier_Store(&eof_, read_result == 0);
171 NoBarrier_Store(&internal_file_error_, read_result);
175 if (cache_.
Write(&io_buffer_[0], read_result) == 0) {
181 void ThreadedIoFile::RunInOutputMode() {
182 DCHECK(internal_file_);
184 DCHECK_EQ(kOutputMode, mode_);
187 uint64_t write_bytes = cache_.
Read(&io_buffer_[0], io_buffer_.size());
188 if (write_bytes == 0) {
192 flush_complete_event_.Signal();
197 uint64_t bytes_written(0);
198 while (bytes_written < write_bytes) {
199 int64_t write_result = internal_file_->Write(
200 &io_buffer_[bytes_written], write_bytes - bytes_written);
201 if (write_result < 0) {
202 NoBarrier_Store(&internal_file_error_, write_result);
206 bytes_written += write_result;