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),
32 flush_complete_event_(false, false),
33 internal_file_error_(0){
34 DCHECK(internal_file_);
37 ThreadedIoFile::~ThreadedIoFile() {}
40 DCHECK(internal_file_);
42 if (!internal_file_->Open())
45 size_ = internal_file_->Size();
48 base::Bind(mode_ == kInputMode ?
49 &ThreadedIoFile::RunInInputMode :
50 &ThreadedIoFile::RunInOutputMode,
51 base::Unretained(
this))));
57 DCHECK(internal_file_);
60 if (mode_ == kOutputMode)
66 bool result = internal_file_.release()->Close();
72 DCHECK(internal_file_);
74 DCHECK_EQ(kInputMode, mode_);
79 if (NoBarrier_Load(&internal_file_error_))
80 return NoBarrier_Load(&internal_file_error_);
82 return cache_.
Read(buffer, length);
86 DCHECK(internal_file_);
88 DCHECK_EQ(kOutputMode, mode_);
90 if (NoBarrier_Load(&internal_file_error_))
91 return NoBarrier_Load(&internal_file_error_);
94 return cache_.
Write(buffer, length);
98 DCHECK(internal_file_);
105 DCHECK(internal_file_);
107 DCHECK_EQ(kOutputMode, mode_);
111 flush_complete_event_.Wait();
112 return internal_file_->Flush();
115 void ThreadedIoFile::RunInInputMode() {
116 DCHECK(internal_file_);
118 DCHECK_EQ(kInputMode, mode_);
121 int64_t read_result = internal_file_->Read(&io_buffer_[0],
123 if (read_result <= 0) {
124 NoBarrier_Store(&eof_, read_result == 0);
125 NoBarrier_Store(&internal_file_error_, read_result);
129 cache_.
Write(&io_buffer_[0], read_result);
143 void ThreadedIoFile::RunInOutputMode() {
144 DCHECK(internal_file_);
146 DCHECK_EQ(kOutputMode, mode_);
149 uint64_t write_bytes = cache_.
Read(&io_buffer_[0], io_buffer_.size());
150 if (write_bytes == 0) {
154 flush_complete_event_.Signal();
159 uint64_t bytes_written(0);
160 while (bytes_written < write_bytes) {
161 int64_t write_result = internal_file_->Write(
162 &io_buffer_[bytes_written], write_bytes - bytes_written);
163 if (write_result < 0) {
164 NoBarrier_Store(&internal_file_error_, write_result);
168 bytes_written += write_result;