OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/disk_cache/in_flight_backend_io.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/compiler_specific.h" | |
10 #include "base/logging.h" | |
11 #include "net/base/net_errors.h" | |
12 #include "net/disk_cache/backend_impl.h" | |
13 #include "net/disk_cache/entry_impl.h" | |
14 #include "net/disk_cache/histogram_macros.h" | |
15 | |
16 namespace disk_cache { | |
17 | |
18 BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, | |
19 const net::CompletionCallback& callback) | |
20 : BackgroundIO(controller), | |
21 backend_(backend), | |
22 callback_(callback), | |
23 operation_(OP_NONE), | |
24 entry_ptr_(NULL), | |
25 iter_ptr_(NULL), | |
26 iter_(NULL), | |
27 entry_(NULL), | |
28 index_(0), | |
29 offset_(0), | |
30 buf_len_(0), | |
31 truncate_(false), | |
32 offset64_(0), | |
33 start_(NULL) { | |
34 start_time_ = base::TimeTicks::Now(); | |
35 } | |
36 | |
37 // Runs on the background thread. | |
38 void BackendIO::ExecuteOperation() { | |
39 if (IsEntryOperation()) | |
40 return ExecuteEntryOperation(); | |
41 | |
42 ExecuteBackendOperation(); | |
43 } | |
44 | |
45 // Runs on the background thread. | |
46 void BackendIO::OnIOComplete(int result) { | |
47 DCHECK(IsEntryOperation()); | |
48 DCHECK_NE(result, net::ERR_IO_PENDING); | |
49 result_ = result; | |
50 NotifyController(); | |
51 } | |
52 | |
53 // Runs on the primary thread. | |
54 void BackendIO::OnDone(bool cancel) { | |
55 if (IsEntryOperation()) { | |
56 CACHE_UMA(TIMES, "TotalIOTime", 0, ElapsedTime()); | |
57 } | |
58 | |
59 if (!ReturnsEntry()) | |
60 return; | |
61 | |
62 if (result() == net::OK) { | |
63 static_cast<EntryImpl*>(*entry_ptr_)->OnEntryCreated(backend_); | |
64 if (cancel) | |
65 (*entry_ptr_)->Close(); | |
66 } | |
67 } | |
68 | |
69 bool BackendIO::IsEntryOperation() { | |
70 return operation_ > OP_MAX_BACKEND; | |
71 } | |
72 | |
73 // Runs on the background thread. | |
74 void BackendIO::ReferenceEntry() { | |
75 entry_->AddRef(); | |
76 } | |
77 | |
78 void BackendIO::Init() { | |
79 operation_ = OP_INIT; | |
80 } | |
81 | |
82 void BackendIO::OpenEntry(const std::string& key, Entry** entry) { | |
83 operation_ = OP_OPEN; | |
84 key_ = key; | |
85 entry_ptr_ = entry; | |
86 } | |
87 | |
88 void BackendIO::CreateEntry(const std::string& key, Entry** entry) { | |
89 operation_ = OP_CREATE; | |
90 key_ = key; | |
91 entry_ptr_ = entry; | |
92 } | |
93 | |
94 void BackendIO::DoomEntry(const std::string& key) { | |
95 operation_ = OP_DOOM; | |
96 key_ = key; | |
97 } | |
98 | |
99 void BackendIO::DoomAllEntries() { | |
100 operation_ = OP_DOOM_ALL; | |
101 } | |
102 | |
103 void BackendIO::DoomEntriesBetween(const base::Time initial_time, | |
104 const base::Time end_time) { | |
105 operation_ = OP_DOOM_BETWEEN; | |
106 initial_time_ = initial_time; | |
107 end_time_ = end_time; | |
108 } | |
109 | |
110 void BackendIO::DoomEntriesSince(const base::Time initial_time) { | |
111 operation_ = OP_DOOM_SINCE; | |
112 initial_time_ = initial_time; | |
113 } | |
114 | |
115 void BackendIO::OpenNextEntry(void** iter, Entry** next_entry) { | |
116 operation_ = OP_OPEN_NEXT; | |
117 iter_ptr_ = iter; | |
118 entry_ptr_ = next_entry; | |
119 } | |
120 | |
121 void BackendIO::OpenPrevEntry(void** iter, Entry** prev_entry) { | |
122 operation_ = OP_OPEN_PREV; | |
123 iter_ptr_ = iter; | |
124 entry_ptr_ = prev_entry; | |
125 } | |
126 | |
127 void BackendIO::EndEnumeration(void* iterator) { | |
128 operation_ = OP_END_ENUMERATION; | |
129 iter_ = iterator; | |
130 } | |
131 | |
132 void BackendIO::OnExternalCacheHit(const std::string& key) { | |
133 operation_ = OP_ON_EXTERNAL_CACHE_HIT; | |
134 key_ = key; | |
135 } | |
136 | |
137 void BackendIO::CloseEntryImpl(EntryImpl* entry) { | |
138 operation_ = OP_CLOSE_ENTRY; | |
139 entry_ = entry; | |
140 } | |
141 | |
142 void BackendIO::DoomEntryImpl(EntryImpl* entry) { | |
143 operation_ = OP_DOOM_ENTRY; | |
144 entry_ = entry; | |
145 } | |
146 | |
147 void BackendIO::FlushQueue() { | |
148 operation_ = OP_FLUSH_QUEUE; | |
149 } | |
150 | |
151 void BackendIO::RunTask(const base::Closure& task) { | |
152 operation_ = OP_RUN_TASK; | |
153 task_ = task; | |
154 } | |
155 | |
156 void BackendIO::ReadData(EntryImpl* entry, int index, int offset, | |
157 net::IOBuffer* buf, int buf_len) { | |
158 operation_ = OP_READ; | |
159 entry_ = entry; | |
160 index_ = index; | |
161 offset_ = offset; | |
162 buf_ = buf; | |
163 buf_len_ = buf_len; | |
164 } | |
165 | |
166 void BackendIO::WriteData(EntryImpl* entry, int index, int offset, | |
167 net::IOBuffer* buf, int buf_len, bool truncate) { | |
168 operation_ = OP_WRITE; | |
169 entry_ = entry; | |
170 index_ = index; | |
171 offset_ = offset; | |
172 buf_ = buf; | |
173 buf_len_ = buf_len; | |
174 truncate_ = truncate; | |
175 } | |
176 | |
177 void BackendIO::ReadSparseData(EntryImpl* entry, int64 offset, | |
178 net::IOBuffer* buf, int buf_len) { | |
179 operation_ = OP_READ_SPARSE; | |
180 entry_ = entry; | |
181 offset64_ = offset; | |
182 buf_ = buf; | |
183 buf_len_ = buf_len; | |
184 } | |
185 | |
186 void BackendIO::WriteSparseData(EntryImpl* entry, int64 offset, | |
187 net::IOBuffer* buf, int buf_len) { | |
188 operation_ = OP_WRITE_SPARSE; | |
189 entry_ = entry; | |
190 offset64_ = offset; | |
191 buf_ = buf; | |
192 buf_len_ = buf_len; | |
193 } | |
194 | |
195 void BackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, int len, | |
196 int64* start) { | |
197 operation_ = OP_GET_RANGE; | |
198 entry_ = entry; | |
199 offset64_ = offset; | |
200 buf_len_ = len; | |
201 start_ = start; | |
202 } | |
203 | |
204 void BackendIO::CancelSparseIO(EntryImpl* entry) { | |
205 operation_ = OP_CANCEL_IO; | |
206 entry_ = entry; | |
207 } | |
208 | |
209 void BackendIO::ReadyForSparseIO(EntryImpl* entry) { | |
210 operation_ = OP_IS_READY; | |
211 entry_ = entry; | |
212 } | |
213 | |
214 BackendIO::~BackendIO() {} | |
215 | |
216 bool BackendIO::ReturnsEntry() { | |
217 return (operation_ == OP_OPEN || operation_ == OP_CREATE || | |
218 operation_ == OP_OPEN_NEXT || operation_ == OP_OPEN_PREV); | |
219 } | |
220 | |
221 base::TimeDelta BackendIO::ElapsedTime() const { | |
222 return base::TimeTicks::Now() - start_time_; | |
223 } | |
224 | |
225 // Runs on the background thread. | |
226 void BackendIO::ExecuteBackendOperation() { | |
227 switch (operation_) { | |
228 case OP_INIT: | |
229 result_ = backend_->SyncInit(); | |
230 break; | |
231 case OP_OPEN: | |
232 result_ = backend_->SyncOpenEntry(key_, entry_ptr_); | |
233 break; | |
234 case OP_CREATE: | |
235 result_ = backend_->SyncCreateEntry(key_, entry_ptr_); | |
236 break; | |
237 case OP_DOOM: | |
238 result_ = backend_->SyncDoomEntry(key_); | |
239 break; | |
240 case OP_DOOM_ALL: | |
241 result_ = backend_->SyncDoomAllEntries(); | |
242 break; | |
243 case OP_DOOM_BETWEEN: | |
244 result_ = backend_->SyncDoomEntriesBetween(initial_time_, end_time_); | |
245 break; | |
246 case OP_DOOM_SINCE: | |
247 result_ = backend_->SyncDoomEntriesSince(initial_time_); | |
248 break; | |
249 case OP_OPEN_NEXT: | |
250 result_ = backend_->SyncOpenNextEntry(iter_ptr_, entry_ptr_); | |
251 break; | |
252 case OP_OPEN_PREV: | |
253 result_ = backend_->SyncOpenPrevEntry(iter_ptr_, entry_ptr_); | |
254 break; | |
255 case OP_END_ENUMERATION: | |
256 backend_->SyncEndEnumeration(iter_); | |
257 result_ = net::OK; | |
258 break; | |
259 case OP_ON_EXTERNAL_CACHE_HIT: | |
260 backend_->SyncOnExternalCacheHit(key_); | |
261 result_ = net::OK; | |
262 break; | |
263 case OP_CLOSE_ENTRY: | |
264 entry_->Release(); | |
265 result_ = net::OK; | |
266 break; | |
267 case OP_DOOM_ENTRY: | |
268 entry_->DoomImpl(); | |
269 result_ = net::OK; | |
270 break; | |
271 case OP_FLUSH_QUEUE: | |
272 result_ = net::OK; | |
273 break; | |
274 case OP_RUN_TASK: | |
275 task_.Run(); | |
276 result_ = net::OK; | |
277 break; | |
278 default: | |
279 NOTREACHED() << "Invalid Operation"; | |
280 result_ = net::ERR_UNEXPECTED; | |
281 } | |
282 DCHECK_NE(net::ERR_IO_PENDING, result_); | |
283 NotifyController(); | |
284 } | |
285 | |
286 // Runs on the background thread. | |
287 void BackendIO::ExecuteEntryOperation() { | |
288 switch (operation_) { | |
289 case OP_READ: | |
290 result_ = | |
291 entry_->ReadDataImpl(index_, offset_, buf_.get(), buf_len_, | |
292 base::Bind(&BackendIO::OnIOComplete, this)); | |
293 break; | |
294 case OP_WRITE: | |
295 result_ = | |
296 entry_->WriteDataImpl(index_, offset_, buf_.get(), buf_len_, | |
297 base::Bind(&BackendIO::OnIOComplete, this), | |
298 truncate_); | |
299 break; | |
300 case OP_READ_SPARSE: | |
301 result_ = entry_->ReadSparseDataImpl( | |
302 offset64_, buf_.get(), buf_len_, | |
303 base::Bind(&BackendIO::OnIOComplete, this)); | |
304 break; | |
305 case OP_WRITE_SPARSE: | |
306 result_ = entry_->WriteSparseDataImpl( | |
307 offset64_, buf_.get(), buf_len_, | |
308 base::Bind(&BackendIO::OnIOComplete, this)); | |
309 break; | |
310 case OP_GET_RANGE: | |
311 result_ = entry_->GetAvailableRangeImpl(offset64_, buf_len_, start_); | |
312 break; | |
313 case OP_CANCEL_IO: | |
314 entry_->CancelSparseIOImpl(); | |
315 result_ = net::OK; | |
316 break; | |
317 case OP_IS_READY: | |
318 result_ = entry_->ReadyForSparseIOImpl( | |
319 base::Bind(&BackendIO::OnIOComplete, this)); | |
320 break; | |
321 default: | |
322 NOTREACHED() << "Invalid Operation"; | |
323 result_ = net::ERR_UNEXPECTED; | |
324 } | |
325 buf_ = NULL; | |
326 if (result_ != net::ERR_IO_PENDING) | |
327 NotifyController(); | |
328 } | |
329 | |
330 InFlightBackendIO::InFlightBackendIO(BackendImpl* backend, | |
331 base::MessageLoopProxy* background_thread) | |
332 : backend_(backend), | |
333 background_thread_(background_thread), | |
334 ptr_factory_(this) { | |
335 } | |
336 | |
337 InFlightBackendIO::~InFlightBackendIO() { | |
338 } | |
339 | |
340 void InFlightBackendIO::Init(const net::CompletionCallback& callback) { | |
341 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
342 operation->Init(); | |
343 PostOperation(operation.get()); | |
344 } | |
345 | |
346 void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry, | |
347 const net::CompletionCallback& callback) { | |
348 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
349 operation->OpenEntry(key, entry); | |
350 PostOperation(operation.get()); | |
351 } | |
352 | |
353 void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, | |
354 const net::CompletionCallback& callback) { | |
355 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
356 operation->CreateEntry(key, entry); | |
357 PostOperation(operation.get()); | |
358 } | |
359 | |
360 void InFlightBackendIO::DoomEntry(const std::string& key, | |
361 const net::CompletionCallback& callback) { | |
362 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
363 operation->DoomEntry(key); | |
364 PostOperation(operation.get()); | |
365 } | |
366 | |
367 void InFlightBackendIO::DoomAllEntries( | |
368 const net::CompletionCallback& callback) { | |
369 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
370 operation->DoomAllEntries(); | |
371 PostOperation(operation.get()); | |
372 } | |
373 | |
374 void InFlightBackendIO::DoomEntriesBetween(const base::Time initial_time, | |
375 const base::Time end_time, | |
376 const net::CompletionCallback& callback) { | |
377 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
378 operation->DoomEntriesBetween(initial_time, end_time); | |
379 PostOperation(operation.get()); | |
380 } | |
381 | |
382 void InFlightBackendIO::DoomEntriesSince( | |
383 const base::Time initial_time, const net::CompletionCallback& callback) { | |
384 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
385 operation->DoomEntriesSince(initial_time); | |
386 PostOperation(operation.get()); | |
387 } | |
388 | |
389 void InFlightBackendIO::OpenNextEntry(void** iter, Entry** next_entry, | |
390 const net::CompletionCallback& callback) { | |
391 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
392 operation->OpenNextEntry(iter, next_entry); | |
393 PostOperation(operation.get()); | |
394 } | |
395 | |
396 void InFlightBackendIO::OpenPrevEntry(void** iter, Entry** prev_entry, | |
397 const net::CompletionCallback& callback) { | |
398 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
399 operation->OpenPrevEntry(iter, prev_entry); | |
400 PostOperation(operation.get()); | |
401 } | |
402 | |
403 void InFlightBackendIO::EndEnumeration(void* iterator) { | |
404 scoped_refptr<BackendIO> operation( | |
405 new BackendIO(this, backend_, net::CompletionCallback())); | |
406 operation->EndEnumeration(iterator); | |
407 PostOperation(operation.get()); | |
408 } | |
409 | |
410 void InFlightBackendIO::OnExternalCacheHit(const std::string& key) { | |
411 scoped_refptr<BackendIO> operation( | |
412 new BackendIO(this, backend_, net::CompletionCallback())); | |
413 operation->OnExternalCacheHit(key); | |
414 PostOperation(operation.get()); | |
415 } | |
416 | |
417 void InFlightBackendIO::CloseEntryImpl(EntryImpl* entry) { | |
418 scoped_refptr<BackendIO> operation( | |
419 new BackendIO(this, backend_, net::CompletionCallback())); | |
420 operation->CloseEntryImpl(entry); | |
421 PostOperation(operation.get()); | |
422 } | |
423 | |
424 void InFlightBackendIO::DoomEntryImpl(EntryImpl* entry) { | |
425 scoped_refptr<BackendIO> operation( | |
426 new BackendIO(this, backend_, net::CompletionCallback())); | |
427 operation->DoomEntryImpl(entry); | |
428 PostOperation(operation.get()); | |
429 } | |
430 | |
431 void InFlightBackendIO::FlushQueue(const net::CompletionCallback& callback) { | |
432 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
433 operation->FlushQueue(); | |
434 PostOperation(operation.get()); | |
435 } | |
436 | |
437 void InFlightBackendIO::RunTask( | |
438 const base::Closure& task, const net::CompletionCallback& callback) { | |
439 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
440 operation->RunTask(task); | |
441 PostOperation(operation.get()); | |
442 } | |
443 | |
444 void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset, | |
445 net::IOBuffer* buf, int buf_len, | |
446 const net::CompletionCallback& callback) { | |
447 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
448 operation->ReadData(entry, index, offset, buf, buf_len); | |
449 PostOperation(operation.get()); | |
450 } | |
451 | |
452 void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, | |
453 net::IOBuffer* buf, int buf_len, | |
454 bool truncate, | |
455 const net::CompletionCallback& callback) { | |
456 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
457 operation->WriteData(entry, index, offset, buf, buf_len, truncate); | |
458 PostOperation(operation.get()); | |
459 } | |
460 | |
461 void InFlightBackendIO::ReadSparseData( | |
462 EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, | |
463 const net::CompletionCallback& callback) { | |
464 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
465 operation->ReadSparseData(entry, offset, buf, buf_len); | |
466 PostOperation(operation.get()); | |
467 } | |
468 | |
469 void InFlightBackendIO::WriteSparseData( | |
470 EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, | |
471 const net::CompletionCallback& callback) { | |
472 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
473 operation->WriteSparseData(entry, offset, buf, buf_len); | |
474 PostOperation(operation.get()); | |
475 } | |
476 | |
477 void InFlightBackendIO::GetAvailableRange( | |
478 EntryImpl* entry, int64 offset, int len, int64* start, | |
479 const net::CompletionCallback& callback) { | |
480 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
481 operation->GetAvailableRange(entry, offset, len, start); | |
482 PostOperation(operation.get()); | |
483 } | |
484 | |
485 void InFlightBackendIO::CancelSparseIO(EntryImpl* entry) { | |
486 scoped_refptr<BackendIO> operation( | |
487 new BackendIO(this, backend_, net::CompletionCallback())); | |
488 operation->CancelSparseIO(entry); | |
489 PostOperation(operation.get()); | |
490 } | |
491 | |
492 void InFlightBackendIO::ReadyForSparseIO( | |
493 EntryImpl* entry, const net::CompletionCallback& callback) { | |
494 scoped_refptr<BackendIO> operation(new BackendIO(this, backend_, callback)); | |
495 operation->ReadyForSparseIO(entry); | |
496 PostOperation(operation.get()); | |
497 } | |
498 | |
499 void InFlightBackendIO::WaitForPendingIO() { | |
500 InFlightIO::WaitForPendingIO(); | |
501 } | |
502 | |
503 void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation, | |
504 bool cancel) { | |
505 BackendIO* op = static_cast<BackendIO*>(operation); | |
506 op->OnDone(cancel); | |
507 | |
508 if (!op->callback().is_null() && (!cancel || op->IsEntryOperation())) | |
509 op->callback().Run(op->result()); | |
510 } | |
511 | |
512 void InFlightBackendIO::PostOperation(BackendIO* operation) { | |
513 background_thread_->PostTask(FROM_HERE, | |
514 base::Bind(&BackendIO::ExecuteOperation, operation)); | |
515 OnOperationPosted(operation); | |
516 } | |
517 | |
518 base::WeakPtr<InFlightBackendIO> InFlightBackendIO::GetWeakPtr() { | |
519 return ptr_factory_.GetWeakPtr(); | |
520 } | |
521 | |
522 } // namespace | |
OLD | NEW |