DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs
threaded_io_file.cc
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/file/threaded_io_file.h"
8 
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"
13 
14 namespace edash_packager {
15 namespace media {
16 
17 ThreadedIoFile::ThreadedIoFile(scoped_ptr<File, FileCloser> internal_file,
18  Mode mode,
19  uint64_t io_cache_size,
20  uint64_t io_block_size)
21  : File(internal_file->file_name()),
22  internal_file_(internal_file.Pass()),
23  mode_(mode),
24  cache_(io_cache_size),
25  io_buffer_(io_block_size),
26  size_(0),
27  eof_(false),
28  internal_file_error_(0) {
29  DCHECK(internal_file_);
30 }
31 
32 ThreadedIoFile::~ThreadedIoFile() {}
33 
35  DCHECK(internal_file_);
36 
37  if (!internal_file_->Open())
38  return false;
39 
40  size_ = internal_file_->Size();
41 
42  thread_.reset(new ClosureThread("ThreadedIoFile",
43  base::Bind(mode_ == kInputMode ?
44  &ThreadedIoFile::RunInInputMode :
45  &ThreadedIoFile::RunInOutputMode,
46  base::Unretained(this))));
47  thread_->Start();
48  return true;
49 }
50 
52  DCHECK(internal_file_);
53  DCHECK(thread_);
54 
55  if (mode_ == kOutputMode)
56  Flush();
57 
58  cache_.Close();
59  thread_->Join();
60 
61  bool result = internal_file_.release()->Close();
62  delete this;
63  return result;
64 }
65 
66 int64_t ThreadedIoFile::Read(void* buffer, uint64_t length) {
67  DCHECK(internal_file_);
68  DCHECK(thread_);
69  DCHECK_EQ(kInputMode, mode_);
70 
71  if (internal_file_error_)
72  return internal_file_error_;
73 
74  if (eof_ && !cache_.BytesCached())
75  return 0;
76 
77  return cache_.Read(buffer, length);
78 }
79 
80 int64_t ThreadedIoFile::Write(const void* buffer, uint64_t length) {
81  DCHECK(internal_file_);
82  DCHECK(thread_);
83  DCHECK_EQ(kOutputMode, mode_);
84 
85  if (internal_file_error_)
86  return internal_file_error_;
87 
88  size_ += length;
89  return cache_.Write(buffer, length);
90 }
91 
93  DCHECK(internal_file_);
94  DCHECK(thread_);
95 
96  return size_;
97 }
98 
100  DCHECK(internal_file_);
101  DCHECK(thread_);
102  DCHECK_EQ(kOutputMode, mode_);
103 
104  cache_.WaitUntilEmptyOrClosed();
105  return internal_file_->Flush();
106 }
107 
108 void ThreadedIoFile::RunInInputMode() {
109  DCHECK(internal_file_);
110  DCHECK(thread_);
111  DCHECK_EQ(kInputMode, mode_);
112 
113  while (true) {
114  int64_t read_result = internal_file_->Read(&io_buffer_[0],
115  io_buffer_.size());
116  if (read_result <= 0) {
117  eof_ = read_result == 0;
118  internal_file_error_ = read_result;
119  cache_.Close();
120  return;
121  }
122  cache_.Write(&io_buffer_[0], read_result);
123  }
124 }
125 
126 bool ThreadedIoFile::Seek(uint64_t position) {
127  NOTIMPLEMENTED();
128  return false;
129 }
130 
131 bool ThreadedIoFile::Tell(uint64_t* position) {
132  NOTIMPLEMENTED();
133  return false;
134 }
135 
136 void ThreadedIoFile::RunInOutputMode() {
137  DCHECK(internal_file_);
138  DCHECK(thread_);
139  DCHECK_EQ(kOutputMode, mode_);
140 
141  while (true) {
142  uint64_t write_bytes = cache_.Read(&io_buffer_[0], io_buffer_.size());
143  if (write_bytes == 0)
144  return;
145 
146  int64_t write_result = internal_file_->Write(&io_buffer_[0], write_bytes);
147  if (write_result < 0) {
148  internal_file_error_ = write_result;
149  cache_.Close();
150  return;
151  }
152  CHECK_EQ(write_result, static_cast<int64_t>(write_bytes));
153  }
154 }
155 
156 } // namespace media
157 } // namespace edash_packager
virtual int64_t Write(const void *buffer, uint64_t length) OVERRIDE
virtual int64_t Read(void *buffer, uint64_t length) OVERRIDE
void WaitUntilEmptyOrClosed()
Waits until the cache is empty or has been closed.
Definition: io_cache.cc:136
uint64_t Write(const void *buffer, uint64_t size)
Definition: io_cache.cc:66
virtual bool Tell(uint64_t *position) OVERRIDE
virtual bool Open() OVERRIDE
Internal open. Should not be used directly.
virtual bool Seek(uint64_t position) OVERRIDE
uint64_t Read(void *buffer, uint64_t size)
Definition: io_cache.cc:38