OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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/compiler_specific.h" | |
8 #include "base/logging.h" | |
9 #include "net/base/net_errors.h" | |
10 #include "net/disk_cache/backend_impl.h" | |
11 #include "net/disk_cache/entry_impl.h" | |
12 | |
13 namespace disk_cache { | |
14 | |
15 BackendIO::BackendIO(InFlightIO* controller, BackendImpl* backend, | |
16 net::CompletionCallback* callback) | |
17 : BackgroundIO(controller), backend_(backend), callback_(callback), | |
18 operation_(OP_NONE), | |
19 ALLOW_THIS_IN_INITIALIZER_LIST( | |
20 my_callback_(this, &BackendIO::OnIOComplete)) { | |
21 } | |
22 | |
23 // Runs on the background thread. | |
24 void BackendIO::ExecuteOperation() { | |
25 if (IsEntryOperation()) | |
26 return ExecuteEntryOperation(); | |
27 | |
28 ExecuteBackendOperation(); | |
29 } | |
30 | |
31 // Runs on the background thread. | |
32 void BackendIO::OnIOComplete(int result) { | |
33 DCHECK(IsEntryOperation()); | |
34 DCHECK_NE(result, net::ERR_IO_PENDING); | |
35 result_ = result; | |
36 controller_->OnIOComplete(this); | |
37 } | |
38 | |
39 bool BackendIO::IsEntryOperation() { | |
40 return operation_ > OP_MAX_BACKEND; | |
41 } | |
42 | |
43 void BackendIO::ReleaseEntry() { | |
44 entry_ = NULL; | |
45 } | |
46 | |
47 void BackendIO::Init() { | |
48 operation_ = OP_INIT; | |
49 } | |
50 | |
51 void BackendIO::OpenEntry(const std::string& key, Entry** entry) { | |
52 operation_ = OP_OPEN; | |
53 key_ = key; | |
54 entry_ptr_ = entry; | |
55 } | |
56 | |
57 void BackendIO::CreateEntry(const std::string& key, Entry** entry) { | |
58 operation_ = OP_CREATE; | |
59 key_ = key; | |
60 entry_ptr_ = entry; | |
61 } | |
62 | |
63 void BackendIO::DoomEntry(const std::string& key) { | |
64 operation_ = OP_DOOM; | |
65 key_ = key; | |
66 } | |
67 | |
68 void BackendIO::DoomAllEntries() { | |
69 operation_ = OP_DOOM_ALL; | |
70 } | |
71 | |
72 void BackendIO::DoomEntriesBetween(const base::Time initial_time, | |
73 const base::Time end_time) { | |
74 operation_ = OP_DOOM_BETWEEN; | |
75 initial_time_ = initial_time; | |
76 end_time_ = end_time; | |
77 } | |
78 | |
79 void BackendIO::DoomEntriesSince(const base::Time initial_time) { | |
80 operation_ = OP_DOOM_SINCE; | |
81 initial_time_ = initial_time; | |
82 } | |
83 | |
84 void BackendIO::OpenNextEntry(void** iter, Entry** next_entry) { | |
85 operation_ = OP_OPEN_NEXT; | |
86 iter_ptr_ = iter; | |
87 entry_ptr_ = next_entry; | |
88 } | |
89 | |
90 void BackendIO::OpenPrevEntry(void** iter, Entry** prev_entry) { | |
91 operation_ = OP_OPEN_PREV; | |
92 iter_ptr_ = iter; | |
93 entry_ptr_ = prev_entry; | |
94 } | |
95 | |
96 void BackendIO::EndEnumeration(void* iterator) { | |
97 operation_ = OP_END_ENUMERATION; | |
98 iter_ = iterator; | |
99 } | |
100 | |
101 void BackendIO::CloseEntryImpl(EntryImpl* entry) { | |
102 operation_ = OP_CLOSE_ENTRY; | |
103 entry_ = entry; | |
104 } | |
105 | |
106 void BackendIO::DoomEntryImpl(EntryImpl* entry) { | |
107 operation_ = OP_DOOM_ENTRY; | |
108 entry_ = entry; | |
109 } | |
110 | |
111 void BackendIO::FlushQueue() { | |
112 operation_ = OP_FLUSH_QUEUE; | |
113 } | |
114 | |
115 void BackendIO::ReadData(EntryImpl* entry, int index, int offset, | |
116 net::IOBuffer* buf, int buf_len) { | |
117 operation_ = OP_READ; | |
118 entry_ = entry; | |
119 index_ = index; | |
120 offset_ = offset; | |
121 buf_ = buf; | |
122 buf_len_ = buf_len; | |
123 } | |
124 | |
125 void BackendIO::WriteData(EntryImpl* entry, int index, int offset, | |
126 net::IOBuffer* buf, int buf_len, bool truncate) { | |
127 operation_ = OP_WRITE; | |
128 entry_ = entry; | |
129 index_ = index; | |
130 offset_ = offset; | |
131 buf_ = buf; | |
132 buf_len_ = buf_len; | |
133 truncate_ = truncate; | |
134 } | |
135 | |
136 void BackendIO::ReadSparseData(EntryImpl* entry, int64 offset, | |
137 net::IOBuffer* buf, int buf_len) { | |
138 operation_ = OP_READ_SPARSE; | |
139 entry_ = entry; | |
140 offset64_ = offset; | |
141 buf_ = buf; | |
142 buf_len_ = buf_len; | |
143 } | |
144 | |
145 void BackendIO::WriteSparseData(EntryImpl* entry, int64 offset, | |
146 net::IOBuffer* buf, int buf_len) { | |
147 operation_ = OP_WRITE_SPARSE; | |
148 entry_ = entry; | |
149 offset64_ = offset; | |
150 buf_ = buf; | |
151 buf_len_ = buf_len; | |
152 } | |
153 | |
154 void BackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, int len, | |
155 int64* start) { | |
156 operation_ = OP_GET_RANGE; | |
157 entry_ = entry; | |
158 offset64_ = offset; | |
159 buf_len_ = len; | |
160 start_ = start; | |
161 } | |
162 | |
163 void BackendIO::CancelSparseIO(EntryImpl* entry) { | |
164 operation_ = OP_CANCEL_IO; | |
165 entry_ = entry; | |
166 } | |
167 | |
168 void BackendIO::ReadyForSparseIO(EntryImpl* entry) { | |
169 operation_ = OP_IS_READY; | |
170 entry_ = entry; | |
171 } | |
172 | |
173 // Runs on the background thread. | |
174 void BackendIO::ExecuteBackendOperation() { | |
175 switch (operation_) { | |
176 case OP_INIT: | |
177 result_ = backend_->SyncInit(); | |
178 break; | |
179 case OP_OPEN: | |
180 result_ = backend_->SyncOpenEntry(key_, entry_ptr_); | |
181 break; | |
182 case OP_CREATE: | |
183 result_ = backend_->SyncCreateEntry(key_, entry_ptr_); | |
184 break; | |
185 case OP_DOOM: | |
186 result_ = backend_->SyncDoomEntry(key_); | |
187 break; | |
188 case OP_DOOM_ALL: | |
189 result_ = backend_->SyncDoomAllEntries(); | |
190 break; | |
191 case OP_DOOM_BETWEEN: | |
192 result_ = backend_->SyncDoomEntriesBetween(initial_time_, end_time_); | |
193 break; | |
194 case OP_DOOM_SINCE: | |
195 result_ = backend_->SyncDoomEntriesSince(initial_time_); | |
196 break; | |
197 case OP_OPEN_NEXT: | |
198 result_ = backend_->SyncOpenNextEntry(iter_ptr_, entry_ptr_); | |
199 break; | |
200 case OP_OPEN_PREV: | |
201 result_ = backend_->SyncOpenPrevEntry(iter_ptr_, entry_ptr_); | |
202 break; | |
203 case OP_END_ENUMERATION: | |
204 backend_->SyncEndEnumeration(iter_); | |
205 result_ = net::OK; | |
206 break; | |
207 case OP_CLOSE_ENTRY: | |
208 entry_->Release(); | |
209 result_ = net::OK; | |
210 break; | |
211 case OP_DOOM_ENTRY: | |
212 entry_->DoomImpl(); | |
213 result_ = net::OK; | |
214 break; | |
215 case OP_FLUSH_QUEUE: | |
216 result_ = net::OK; | |
217 break; | |
218 default: | |
219 NOTREACHED() << "Invalid Operation"; | |
220 result_ = net::ERR_UNEXPECTED; | |
221 } | |
222 DCHECK_NE(net::ERR_IO_PENDING, result_); | |
223 controller_->OnIOComplete(this); | |
224 } | |
225 | |
226 // Runs on the background thread. | |
227 void BackendIO::ExecuteEntryOperation() { | |
228 switch (operation_) { | |
229 case OP_READ: | |
230 result_ = entry_->ReadDataImpl(index_, offset_, buf_, buf_len_, | |
231 &my_callback_); | |
232 break; | |
233 case OP_WRITE: | |
234 result_ = entry_->WriteDataImpl(index_, offset_, buf_, buf_len_, | |
235 &my_callback_, truncate_); | |
236 break; | |
237 case OP_READ_SPARSE: | |
238 result_ = entry_->ReadSparseDataImpl(offset64_, buf_, buf_len_, | |
239 &my_callback_); | |
240 break; | |
241 case OP_WRITE_SPARSE: | |
242 result_ = entry_->WriteSparseDataImpl(offset64_, buf_, buf_len_, | |
243 &my_callback_); | |
244 break; | |
245 case OP_GET_RANGE: | |
246 result_ = entry_->GetAvailableRangeImpl(offset64_, buf_len_, start_); | |
247 break; | |
248 case OP_CANCEL_IO: | |
249 entry_->CancelSparseIOImpl(); | |
250 result_ = net::OK; | |
251 break; | |
252 case OP_IS_READY: | |
253 result_ = entry_->ReadyForSparseIOImpl(&my_callback_); | |
254 break; | |
255 default: | |
256 NOTREACHED() << "Invalid Operation"; | |
257 result_ = net::ERR_UNEXPECTED; | |
258 } | |
259 if (result_ != net::ERR_IO_PENDING) | |
260 controller_->OnIOComplete(this); | |
261 } | |
262 | |
263 // --------------------------------------------------------------------------- | |
264 | |
265 void InFlightBackendIO::Init(CompletionCallback* callback) { | |
266 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
267 operation->Init(); | |
268 QueueOperation(operation); | |
269 } | |
270 | |
271 void InFlightBackendIO::OpenEntry(const std::string& key, Entry** entry, | |
272 CompletionCallback* callback) { | |
273 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
274 operation->OpenEntry(key, entry); | |
275 QueueOperation(operation); | |
276 } | |
277 | |
278 void InFlightBackendIO::CreateEntry(const std::string& key, Entry** entry, | |
279 CompletionCallback* callback) { | |
280 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
281 operation->CreateEntry(key, entry); | |
282 QueueOperation(operation); | |
283 } | |
284 | |
285 void InFlightBackendIO::DoomEntry(const std::string& key, | |
286 CompletionCallback* callback) { | |
287 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
288 operation->DoomEntry(key); | |
289 QueueOperation(operation); | |
290 } | |
291 | |
292 void InFlightBackendIO::DoomAllEntries(CompletionCallback* callback) { | |
293 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
294 operation->DoomAllEntries(); | |
295 QueueOperation(operation); | |
296 } | |
297 | |
298 void InFlightBackendIO::DoomEntriesBetween(const base::Time initial_time, | |
299 const base::Time end_time, | |
300 CompletionCallback* callback) { | |
301 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
302 operation->DoomEntriesBetween(initial_time, end_time); | |
303 QueueOperation(operation); | |
304 } | |
305 | |
306 void InFlightBackendIO::DoomEntriesSince(const base::Time initial_time, | |
307 CompletionCallback* callback) { | |
308 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
309 operation->DoomEntriesSince(initial_time); | |
310 QueueOperation(operation); | |
311 } | |
312 | |
313 void InFlightBackendIO::OpenNextEntry(void** iter, Entry** next_entry, | |
314 CompletionCallback* callback) { | |
315 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
316 operation->OpenNextEntry(iter, next_entry); | |
317 QueueOperation(operation); | |
318 } | |
319 | |
320 void InFlightBackendIO::OpenPrevEntry(void** iter, Entry** prev_entry, | |
321 CompletionCallback* callback) { | |
322 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
323 operation->OpenPrevEntry(iter, prev_entry); | |
324 QueueOperation(operation); | |
325 } | |
326 | |
327 void InFlightBackendIO::EndEnumeration(void* iterator) { | |
328 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); | |
329 operation->EndEnumeration(iterator); | |
330 QueueOperation(operation); | |
331 } | |
332 | |
333 void InFlightBackendIO::CloseEntryImpl(EntryImpl* entry) { | |
334 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); | |
335 operation->CloseEntryImpl(entry); | |
336 QueueOperation(operation); | |
337 } | |
338 | |
339 void InFlightBackendIO::DoomEntryImpl(EntryImpl* entry) { | |
340 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); | |
341 operation->DoomEntryImpl(entry); | |
342 QueueOperation(operation); | |
343 } | |
344 | |
345 void InFlightBackendIO::FlushQueue(net::CompletionCallback* callback) { | |
346 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
347 operation->FlushQueue(); | |
348 QueueOperation(operation); | |
349 } | |
350 | |
351 void InFlightBackendIO::ReadData(EntryImpl* entry, int index, int offset, | |
352 net::IOBuffer* buf, int buf_len, | |
353 CompletionCallback* callback) { | |
354 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
355 operation->ReadData(entry, index, offset, buf, buf_len); | |
356 QueueOperation(operation); | |
357 } | |
358 | |
359 void InFlightBackendIO::WriteData(EntryImpl* entry, int index, int offset, | |
360 net::IOBuffer* buf, int buf_len, | |
361 bool truncate, | |
362 CompletionCallback* callback) { | |
363 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
364 operation->WriteData(entry, index, offset, buf, buf_len, truncate); | |
365 QueueOperation(operation); | |
366 } | |
367 | |
368 void InFlightBackendIO::ReadSparseData(EntryImpl* entry, int64 offset, | |
369 net::IOBuffer* buf, int buf_len, | |
370 CompletionCallback* callback) { | |
371 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
372 operation->ReadSparseData(entry, offset, buf, buf_len); | |
373 QueueOperation(operation); | |
374 } | |
375 | |
376 void InFlightBackendIO::WriteSparseData(EntryImpl* entry, int64 offset, | |
377 net::IOBuffer* buf, int buf_len, | |
378 CompletionCallback* callback) { | |
379 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
380 operation->WriteSparseData(entry, offset, buf, buf_len); | |
381 QueueOperation(operation); | |
382 } | |
383 | |
384 void InFlightBackendIO::GetAvailableRange(EntryImpl* entry, int64 offset, | |
385 int len, int64* start, | |
386 CompletionCallback* callback) { | |
387 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
388 operation->GetAvailableRange(entry, offset, len, start); | |
389 QueueOperation(operation); | |
390 } | |
391 | |
392 void InFlightBackendIO::CancelSparseIO(EntryImpl* entry) { | |
393 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, NULL); | |
394 operation->ReadyForSparseIO(entry); | |
395 QueueOperation(operation); | |
396 } | |
397 | |
398 void InFlightBackendIO::ReadyForSparseIO(EntryImpl* entry, | |
399 CompletionCallback* callback) { | |
400 scoped_refptr<BackendIO> operation = new BackendIO(this, backend_, callback); | |
401 operation->ReadyForSparseIO(entry); | |
402 QueueOperation(operation); | |
403 } | |
404 | |
405 void InFlightBackendIO::WaitForPendingIO() { | |
406 // We clear the list first so that we don't post more operations after this | |
407 // point. | |
408 pending_ops_.clear(); | |
409 InFlightIO::WaitForPendingIO(); | |
410 } | |
411 | |
412 void InFlightBackendIO::OnOperationComplete(BackgroundIO* operation, | |
413 bool cancel) { | |
414 BackendIO* op = static_cast<BackendIO*>(operation); | |
415 | |
416 if (!op->IsEntryOperation() && !pending_ops_.empty()) { | |
417 // Process the next request. Note that invoking the callback may result | |
418 // in the backend destruction (and with it this object), so we should deal | |
419 // with the next operation before invoking the callback. | |
420 scoped_refptr<BackendIO> next_op = pending_ops_.front(); | |
421 pending_ops_.pop_front(); | |
422 PostOperation(next_op); | |
423 } | |
424 | |
425 if (op->callback() && (!cancel || op->IsEntryOperation())) | |
426 op->callback()->Run(op->result()); | |
427 | |
428 if (cancel) | |
429 op->ReleaseEntry(); | |
430 } | |
431 | |
432 void InFlightBackendIO::QueueOperation(BackendIO* operation) { | |
433 if (operation->IsEntryOperation()) | |
434 return PostOperation(operation); | |
435 | |
436 if (pending_ops_.empty()) | |
437 return PostOperation(operation); | |
438 | |
439 pending_ops_.push_back(operation); | |
440 } | |
441 | |
442 void InFlightBackendIO::PostOperation(BackendIO* operation) { | |
443 background_thread_->PostTask(FROM_HERE, | |
444 NewRunnableMethod(operation, &BackendIO::ExecuteOperation)); | |
445 OnOperationPosted(operation); | |
446 } | |
447 | |
448 } // namespace | |
OLD | NEW |