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