OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/plugins/ppapi/quota_file_io.h" | 5 #include "webkit/plugins/ppapi/quota_file_io.h" |
6 | 6 |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
9 #include "base/task.h" | 9 #include "base/task.h" |
10 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 10 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 if (!base::FileUtilProxy::Write( | 93 if (!base::FileUtilProxy::Write( |
94 quota_io_->instance_->delegate()->GetFileThreadMessageLoopProxy(), | 94 quota_io_->instance_->delegate()->GetFileThreadMessageLoopProxy(), |
95 quota_io_->file_, offset_, buffer_.get(), bytes_to_write_, | 95 quota_io_->file_, offset_, buffer_.get(), bytes_to_write_, |
96 callback_factory_.NewCallback(&WriteOperation::DidFinish))) { | 96 callback_factory_.NewCallback(&WriteOperation::DidFinish))) { |
97 DidFail(base::PLATFORM_FILE_ERROR_FAILED); | 97 DidFail(base::PLATFORM_FILE_ERROR_FAILED); |
98 return; | 98 return; |
99 } | 99 } |
100 } | 100 } |
101 | 101 |
102 virtual void DidFail(PlatformFileError error) OVERRIDE { | 102 virtual void DidFail(PlatformFileError error) OVERRIDE { |
103 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( | 103 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( |
yzshen1
2011/08/04 20:27:38
Would you please explain why this needs to be a po
kinuko
2011/08/05 18:29:56
The reason for these added post-tasks is: Run() is
yzshen1
2011/08/05 20:31:46
Thanks for explaining.
On 2011/08/05 18:29:56, ki
| |
104 FROM_HERE, runnable_factory_.NewRunnableMethod( | 104 FROM_HERE, runnable_factory_.NewRunnableMethod( |
105 &WriteOperation::DidFinish, error, 0)); | 105 &WriteOperation::DidFinish, error, 0)); |
106 } | 106 } |
107 | 107 |
108 bool finished() const { return finished_; } | 108 bool finished() const { return finished_; } |
109 | 109 |
110 void RunCallbackSoon() { | |
111 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( | |
112 FROM_HERE, runnable_factory_.NewRunnableMethod( | |
113 &WriteOperation::RunCallback)); | |
114 } | |
115 | |
116 private: | |
110 void RunCallback() { | 117 void RunCallback() { |
111 DCHECK(callback_.get()); | 118 DCHECK(callback_.get()); |
112 callback_->Run(status_, bytes_written_); | 119 callback_->Run(status_, bytes_written_); |
113 callback_.reset(); | 120 callback_.reset(); |
114 delete this; | 121 delete this; |
115 } | 122 } |
116 | 123 |
117 private: | |
118 void DidFinish(PlatformFileError status, int bytes_written) { | 124 void DidFinish(PlatformFileError status, int bytes_written) { |
119 finished_ = true; | 125 finished_ = true; |
120 status_ = status; | 126 status_ = status; |
121 bytes_written_ = bytes_written; | 127 bytes_written_ = bytes_written; |
122 int64_t max_offset = | 128 int64_t max_offset = |
123 (status != base::PLATFORM_FILE_OK) ? 0 : offset_ + bytes_written; | 129 (status != base::PLATFORM_FILE_OK) ? 0 : offset_ + bytes_written; |
124 // This may delete itself by calling RunCallback. | 130 // This may delete itself by calling RunCallback. |
125 quota_io_->DidWrite(this, max_offset); | 131 quota_io_->DidWrite(this, max_offset); |
126 } | 132 } |
127 | 133 |
128 const int64_t offset_; | 134 const int64_t offset_; |
129 scoped_array<char> buffer_; | 135 scoped_array<char> buffer_; |
130 const int32_t bytes_to_write_; | 136 const int32_t bytes_to_write_; |
131 scoped_ptr<WriteCallback> callback_; | 137 scoped_ptr<WriteCallback> callback_; |
132 bool finished_; | 138 bool finished_; |
133 PlatformFileError status_; | 139 PlatformFileError status_; |
134 int64_t bytes_written_; | 140 int64_t bytes_written_; |
135 base::ScopedCallbackFactory<QuotaFileIO::WriteOperation> callback_factory_; | 141 base::ScopedCallbackFactory<QuotaFileIO::WriteOperation> callback_factory_; |
136 ScopedRunnableMethodFactory<QuotaFileIO::WriteOperation> runnable_factory_; | 142 ScopedRunnableMethodFactory<QuotaFileIO::WriteOperation> runnable_factory_; |
137 }; | 143 }; |
138 | 144 |
139 class QuotaFileIO::SetLengthOperation : public PendingOperationBase { | 145 class QuotaFileIO::SetLengthOperation : public PendingOperationBase { |
140 public: | 146 public: |
141 SetLengthOperation(QuotaFileIO* quota_io, | 147 SetLengthOperation(QuotaFileIO* quota_io, |
142 bool is_will_operation, | 148 bool is_will_operation, |
143 int64_t length, | 149 int64_t length, |
144 StatusCallback* callback) | 150 StatusCallback* callback) |
145 : PendingOperationBase(quota_io, is_will_operation), | 151 : PendingOperationBase(quota_io, is_will_operation), |
146 length_(length), | 152 length_(length), |
153 status_(base::PLATFORM_FILE_OK), | |
147 callback_(callback), | 154 callback_(callback), |
148 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 155 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
149 runnable_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} | 156 runnable_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} |
150 virtual ~SetLengthOperation() {} | 157 virtual ~SetLengthOperation() {} |
151 | 158 |
152 virtual void Run() OVERRIDE { | 159 virtual void Run() OVERRIDE { |
153 DCHECK(quota_io_); | 160 DCHECK(quota_io_); |
154 if (quota_io_->CheckIfExceedsQuota(length_)) { | 161 if (quota_io_->CheckIfExceedsQuota(length_)) { |
155 DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); | 162 DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE); |
156 return; | 163 return; |
157 } | 164 } |
158 if (is_will_operation_) { | 165 if (is_will_operation_) { |
159 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( | 166 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( |
160 FROM_HERE, runnable_factory_.NewRunnableMethod( | 167 FROM_HERE, runnable_factory_.NewRunnableMethod( |
161 &SetLengthOperation::DidFinish, | 168 &SetLengthOperation::DidFinish, base::PLATFORM_FILE_OK)); |
162 base::PLATFORM_FILE_OK)); | |
163 return; | 169 return; |
164 } | 170 } |
165 if (!base::FileUtilProxy::Truncate( | 171 if (!base::FileUtilProxy::Truncate( |
166 quota_io_->instance_->delegate()->GetFileThreadMessageLoopProxy(), | 172 quota_io_->instance_->delegate()->GetFileThreadMessageLoopProxy(), |
167 quota_io_->file_, length_, | 173 quota_io_->file_, length_, |
168 callback_factory_.NewCallback(&SetLengthOperation::DidFinish))) { | 174 callback_factory_.NewCallback(&SetLengthOperation::DidFinish))) { |
169 DidFail(base::PLATFORM_FILE_ERROR_FAILED); | 175 DidFail(base::PLATFORM_FILE_ERROR_FAILED); |
170 return; | 176 return; |
171 } | 177 } |
172 } | 178 } |
173 | 179 |
174 virtual void DidFail(PlatformFileError error) OVERRIDE { | 180 virtual void DidFail(PlatformFileError error) OVERRIDE { |
175 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( | 181 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( |
176 FROM_HERE, runnable_factory_.NewRunnableMethod( | 182 FROM_HERE, runnable_factory_.NewRunnableMethod( |
177 &SetLengthOperation::DidFinish, error)); | 183 &SetLengthOperation::DidFinish, error)); |
178 } | 184 } |
179 | 185 |
180 private: | 186 private: |
181 void DidFinish(PlatformFileError status) { | 187 void DidFinish(PlatformFileError status) { |
182 quota_io_->DidSetLength(status, length_); | 188 quota_io_->DidSetLength(status, length_); |
189 status_ = status; | |
190 base::MessageLoopProxy::CreateForCurrentThread()->PostTask( | |
191 FROM_HERE, runnable_factory_.NewRunnableMethod( | |
192 &SetLengthOperation::RunCallback)); | |
193 } | |
194 | |
195 void RunCallback() { | |
183 DCHECK(callback_.get()); | 196 DCHECK(callback_.get()); |
184 callback_->Run(status); | 197 callback_->Run(status_); |
185 callback_.reset(); | 198 callback_.reset(); |
186 delete this; | 199 delete this; |
187 } | 200 } |
188 | 201 |
189 int64_t length_; | 202 int64_t length_; |
203 PlatformFileError status_; | |
190 scoped_ptr<StatusCallback> callback_; | 204 scoped_ptr<StatusCallback> callback_; |
191 base::ScopedCallbackFactory<QuotaFileIO::SetLengthOperation> | 205 base::ScopedCallbackFactory<QuotaFileIO::SetLengthOperation> |
192 callback_factory_; | 206 callback_factory_; |
193 ScopedRunnableMethodFactory<QuotaFileIO::SetLengthOperation> | 207 ScopedRunnableMethodFactory<QuotaFileIO::SetLengthOperation> |
194 runnable_factory_; | 208 runnable_factory_; |
195 }; | 209 }; |
196 | 210 |
197 // QuotaFileIO -------------------------------------------------------------- | 211 // QuotaFileIO -------------------------------------------------------------- |
198 | 212 |
199 QuotaFileIO::QuotaFileIO( | 213 QuotaFileIO::QuotaFileIO( |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 int64_t written_offset_end) { | 346 int64_t written_offset_end) { |
333 max_written_offset_ = std::max(max_written_offset_, written_offset_end); | 347 max_written_offset_ = std::max(max_written_offset_, written_offset_end); |
334 DCHECK_GT(inflight_operations_, 0); | 348 DCHECK_GT(inflight_operations_, 0); |
335 DCHECK(!pending_operations_.empty()); | 349 DCHECK(!pending_operations_.empty()); |
336 // Fire callbacks for finished operations. | 350 // Fire callbacks for finished operations. |
337 while (!pending_operations_.empty()) { | 351 while (!pending_operations_.empty()) { |
338 WriteOperation* op = static_cast<WriteOperation*>( | 352 WriteOperation* op = static_cast<WriteOperation*>( |
339 pending_operations_.front()); | 353 pending_operations_.front()); |
340 if (!op->finished()) | 354 if (!op->finished()) |
341 break; | 355 break; |
342 op->RunCallback(); | |
343 pending_operations_.pop_front(); | 356 pending_operations_.pop_front(); |
357 op->RunCallbackSoon(); | |
344 } | 358 } |
345 // If we have no more pending writes, notify the browser that we did | 359 // If we have no more pending writes, notify the browser that we did |
346 // update the file. | 360 // update the file. |
347 if (--inflight_operations_ == 0) { | 361 if (--inflight_operations_ == 0) { |
348 DCHECK(pending_operations_.empty()); | 362 DCHECK(pending_operations_.empty()); |
349 int64_t growth = max_written_offset_ - cached_file_size_; | 363 int64_t growth = max_written_offset_ - cached_file_size_; |
350 growth = growth < 0 ? 0 : growth; | 364 growth = growth < 0 ? 0 : growth; |
351 instance_->delegate()->DidUpdateFile(file_url_, growth); | 365 instance_->delegate()->DidUpdateFile(file_url_, growth); |
352 max_written_offset_ = 0; | 366 max_written_offset_ = 0; |
353 } | 367 } |
354 } | 368 } |
355 | 369 |
356 void QuotaFileIO::DidSetLength(PlatformFileError error, int64_t new_file_size) { | 370 void QuotaFileIO::DidSetLength(PlatformFileError error, int64_t new_file_size) { |
357 DCHECK_EQ(1, inflight_operations_); | 371 DCHECK_EQ(1, inflight_operations_); |
358 pending_operations_.pop_front(); | 372 pending_operations_.pop_front(); |
359 DCHECK(pending_operations_.empty()); | 373 DCHECK(pending_operations_.empty()); |
360 int64_t delta = (error != base::PLATFORM_FILE_OK) ? 0 : | 374 int64_t delta = (error != base::PLATFORM_FILE_OK) ? 0 : |
361 new_file_size - cached_file_size_; | 375 new_file_size - cached_file_size_; |
362 instance_->delegate()->DidUpdateFile(file_url_, delta); | 376 instance_->delegate()->DidUpdateFile(file_url_, delta); |
363 inflight_operations_ = 0; | 377 inflight_operations_ = 0; |
364 } | 378 } |
365 | 379 |
366 } // namespace ppapi | 380 } // namespace ppapi |
367 } // namespace webkit | 381 } // namespace webkit |
OLD | NEW |