Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: content/browser/service_worker/service_worker_cache_writer.cc

Issue 1315443003: ServiceWorkerWriteToCacheJob: refactor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: first draft Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "content/browser/service_worker/service_worker_cache_writer.h"
6
7 #include <string>
8
9 #include "content/browser/appcache/appcache_response.h"
10 #include "content/browser/service_worker/service_worker_disk_cache.h"
11 #include "content/browser/service_worker/service_worker_storage.h"
12
13 namespace {
14
15 const size_t kCopyBufferSize = 16 * 1024;
16
17 enum {
18 STATE_READ_HEADERS_FOR_COMPARE,
19 STATE_READ_HEADERS_FOR_COMPARE_DONE,
20 STATE_READ_DATA_FOR_COMPARE,
21 STATE_READ_DATA_FOR_COMPARE_DONE,
22 STATE_READ_HEADERS_FOR_COPY,
23 STATE_READ_HEADERS_FOR_COPY_DONE,
24 STATE_READ_DATA_FOR_COPY,
25 STATE_READ_DATA_FOR_COPY_DONE,
26 STATE_WRITE_HEADERS_FOR_PASSTHROUGH,
27 STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE,
28 STATE_WRITE_DATA_FOR_PASSTHROUGH,
29 STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE,
30 STATE_WRITE_HEADERS_FOR_COPY,
31 STATE_WRITE_HEADERS_FOR_COPY_DONE,
32 STATE_WRITE_DATA_FOR_COPY,
33 STATE_WRITE_DATA_FOR_COPY_DONE,
34 };
35
36 // Shim class used to turn always-async functions into async-or-result
37 // functions. See the comments below near ReadInfoHelper.
38 class AsyncOnlyCompletionCallbackAdaptor
39 : public base::RefCounted<AsyncOnlyCompletionCallbackAdaptor> {
40 public:
41 AsyncOnlyCompletionCallbackAdaptor(const net::CompletionCallback& callback)
42 : done_(false),
43 async_(false),
44 result_(net::ERR_IO_PENDING),
45 callback_(callback) {}
46
47 void set_async(bool async) { async_ = async; }
48 bool async() { return async_; }
49 bool done() { return done_; }
50 int result() { return result_; }
51
52 void WrappedCallback(int result) {
53 result_ = result;
54 if (async_)
55 callback_.Run(result);
56 else
57 done_ = true;
58 }
59
60 private:
61 friend class base::RefCounted<AsyncOnlyCompletionCallbackAdaptor>;
62 virtual ~AsyncOnlyCompletionCallbackAdaptor() {}
63
64 bool done_;
65 bool async_;
66 int result_;
67 net::CompletionCallback callback_;
68 };
69
70 } // namespace
71
72 namespace content {
73
74 ServiceWorkerCacheWriter::StateMachine::State::State() {}
75
76 ServiceWorkerCacheWriter::StateMachine::State::State(
77 int id,
78 const std::string& name,
79 const StateMachine::Handler& handler)
80 : id(id), name(name), handler(handler) {}
81
82 ServiceWorkerCacheWriter::StateMachine::State::~State() {}
83
84 ServiceWorkerCacheWriter::StateMachine::StateMachine() : state_(STATE_START) {}
85 ServiceWorkerCacheWriter::StateMachine::~StateMachine() {}
86
87 void ServiceWorkerCacheWriter::StateMachine::AddState(
88 int id,
89 const std::string& name,
90 const StateMachine::Handler& handler) {
91 State state(id, name, handler);
92 states_[id] = state;
93 }
94
95 void ServiceWorkerCacheWriter::StateMachine::AddTransition(int from_id,
96 int to_id) {
97 DCHECK_EQ(1U, states_.count(from_id));
98 DCHECK_EQ(1U, states_.count(to_id));
99 DCHECK_NE(to_id, STATE_START);
100 DCHECK_NE(from_id, STATE_DONE);
101 states_[from_id].allowed_to.insert(to_id);
102 }
103
104 void ServiceWorkerCacheWriter::StateMachine::CheckValidTransition(int from_id,
105 int to_id) {
106 DCHECK_EQ(1U, states_.count(from_id)) << " State " << from_id
107 << " does not exist.";
108 DCHECK_EQ(1U, states_.count(to_id)) << " State " << to_id << " (from "
109 << states_[from_id].name
110 << ") does not exist.";
111 if (to_id == STATE_DONE)
112 return;
113 DCHECK_EQ(1U, states_[from_id].allowed_to.count(to_id))
114 << " Transition from " << states_[from_id].name << " to "
115 << states_[to_id].name << " is not allowed.";
116 }
117
118 int ServiceWorkerCacheWriter::StateMachine::Run(int status) {
119 DCHECK_EQ(1U, states_.count(state_));
120 bool pause = false;
121 VLOG(1) << "Run: initial " << states_[state_].name;
122 do {
123 int next_state = -1;
124 VLOG(1) << " running " << states_[state_].name;
125 status = states_[state_].handler.Run(&next_state, &pause, status);
126 VLOG(1) << " -> " << states_[next_state].name << " " << pause << " "
127 << status;
128 CheckValidTransition(state_, next_state);
129 state_ = next_state;
130 } while (status >= net::OK && state_ != STATE_DONE && !pause);
131 return status;
132 }
133
134 ServiceWorkerCacheWriter::ServiceWorkerCacheWriter(
135 const ResponseReaderCreator& reader_creator,
136 const ResponseWriterCreator& writer_creator)
137 : reader_creator_(reader_creator),
138 writer_creator_(writer_creator),
139 weak_factory_(this) {
140 // This macro defines the state |id| to be named "name" and be bound to this
141 // object's method called name, so:
142 // DEFINE_STATE(STATE_FOO, Foo)
143 // Defines a state STATE_FOO, named "Foo", that is bound to this->Foo().
144 #define DEFINE_STATE(id, name) \
145 state_machine_.AddState( \
146 id, #name, \
147 base::Bind(&ServiceWorkerCacheWriter::name, base::Unretained(this)))
148
149 DEFINE_STATE(StateMachine::STATE_START, Start);
150 DEFINE_STATE(StateMachine::STATE_DONE, Done);
151
152 DEFINE_STATE(STATE_WRITE_HEADERS_FOR_PASSTHROUGH, WriteHeadersForPassthrough);
153 DEFINE_STATE(STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE,
154 WriteHeadersForPassthroughDone);
155 DEFINE_STATE(STATE_WRITE_DATA_FOR_PASSTHROUGH, WriteDataForPassthrough);
156 DEFINE_STATE(STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE,
157 WriteDataForPassthroughDone);
158
159 DEFINE_STATE(STATE_READ_HEADERS_FOR_COMPARE, ReadHeadersForCompare);
160 DEFINE_STATE(STATE_READ_HEADERS_FOR_COMPARE_DONE, ReadHeadersForCompareDone);
161 DEFINE_STATE(STATE_READ_DATA_FOR_COMPARE, ReadDataForCompare);
162 DEFINE_STATE(STATE_READ_DATA_FOR_COMPARE_DONE, ReadDataForCompareDone);
163
164 DEFINE_STATE(STATE_READ_HEADERS_FOR_COPY, ReadHeadersForCopy);
165 DEFINE_STATE(STATE_READ_HEADERS_FOR_COPY_DONE, ReadHeadersForCopyDone);
166 DEFINE_STATE(STATE_WRITE_HEADERS_FOR_COPY, WriteHeadersForCopy);
167 DEFINE_STATE(STATE_WRITE_HEADERS_FOR_COPY_DONE, WriteHeadersForCopyDone);
168
169 DEFINE_STATE(STATE_READ_DATA_FOR_COPY, ReadDataForCopy);
170 DEFINE_STATE(STATE_READ_DATA_FOR_COPY_DONE, ReadDataForCopyDone);
171 DEFINE_STATE(STATE_WRITE_DATA_FOR_COPY, WriteDataForCopy);
172 DEFINE_STATE(STATE_WRITE_DATA_FOR_COPY_DONE, WriteDataForCopyDone);
173
174 #undef DEFINE_STATE
175
176 state_machine_.AddTransition(StateMachine::STATE_START,
177 STATE_WRITE_HEADERS_FOR_PASSTHROUGH);
178 state_machine_.AddTransition(StateMachine::STATE_START,
179 STATE_READ_HEADERS_FOR_COMPARE);
180 // The passthrough write loop:
181 // WriteHeaders -> WriteHeadersDone -> WriteData -> WriteDataDone
182 // -> WriteData
183 state_machine_.AddTransition(STATE_WRITE_HEADERS_FOR_PASSTHROUGH,
184 STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE);
185 state_machine_.AddTransition(STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE,
186 STATE_WRITE_DATA_FOR_PASSTHROUGH);
187 state_machine_.AddTransition(STATE_WRITE_DATA_FOR_PASSTHROUGH,
188 STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE);
189 state_machine_.AddTransition(STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE,
190 STATE_WRITE_DATA_FOR_PASSTHROUGH);
191
192 // The comparator loop:
193 // ReadHeaders -> ReadHeadersDone -> ReadData -> ReadDataDone -> ReadData
194 // Exits via ReadHeadersForCopy.
195 // ReadDataForCompareDone has a self-edge, see the comments in the
196 // function for details.
197 state_machine_.AddTransition(STATE_READ_HEADERS_FOR_COMPARE,
198 STATE_READ_HEADERS_FOR_COMPARE_DONE);
199 state_machine_.AddTransition(STATE_READ_HEADERS_FOR_COMPARE_DONE,
200 STATE_READ_DATA_FOR_COMPARE);
201 state_machine_.AddTransition(STATE_READ_DATA_FOR_COMPARE,
202 STATE_READ_DATA_FOR_COMPARE_DONE);
203 state_machine_.AddTransition(STATE_READ_DATA_FOR_COMPARE_DONE,
204 STATE_READ_DATA_FOR_COMPARE);
205 state_machine_.AddTransition(STATE_READ_DATA_FOR_COMPARE_DONE,
206 STATE_READ_DATA_FOR_COMPARE_DONE);
207 state_machine_.AddTransition(STATE_READ_DATA_FOR_COMPARE_DONE,
208 STATE_READ_HEADERS_FOR_COPY);
209
210 // ReadHeaders -> ReadHeadersDone -> WriteHeaders -> WriteHeadersDone
211 // -> ReadData
212 state_machine_.AddTransition(STATE_READ_HEADERS_FOR_COPY,
213 STATE_READ_HEADERS_FOR_COPY_DONE);
214 state_machine_.AddTransition(STATE_READ_HEADERS_FOR_COPY_DONE,
215 STATE_WRITE_HEADERS_FOR_COPY);
216 state_machine_.AddTransition(STATE_WRITE_HEADERS_FOR_COPY,
217 STATE_WRITE_HEADERS_FOR_COPY_DONE);
218 state_machine_.AddTransition(STATE_WRITE_HEADERS_FOR_COPY_DONE,
219 STATE_READ_DATA_FOR_COPY);
220
221 // The ReadDataForCopy loop:
222 // ReadData -> ReadDataDone -> WriteData -> WriteDataDone -> ReadData
223 // This can bail out via:
224 // ReadData -> WriteDataForPassthrough
225 state_machine_.AddTransition(STATE_READ_DATA_FOR_COPY,
226 STATE_READ_DATA_FOR_COPY_DONE);
227 state_machine_.AddTransition(STATE_READ_DATA_FOR_COPY_DONE,
228 STATE_WRITE_DATA_FOR_COPY);
229 state_machine_.AddTransition(STATE_WRITE_DATA_FOR_COPY,
230 STATE_WRITE_DATA_FOR_COPY_DONE);
231 state_machine_.AddTransition(STATE_WRITE_DATA_FOR_COPY_DONE,
232 STATE_READ_DATA_FOR_COPY);
233 state_machine_.AddTransition(STATE_READ_DATA_FOR_COPY,
234 STATE_WRITE_DATA_FOR_PASSTHROUGH);
235 }
236
237 ServiceWorkerCacheWriter::~ServiceWorkerCacheWriter() {}
238
239 net::Error ServiceWorkerCacheWriter::WriteHeaders(
240 HttpResponseInfoIOBuffer* headers,
241 const OnWriteCompleteCallback& callback) {
242 headers_to_write_ = headers;
243 pending_callback_ = callback;
244 int result = state_machine_.Run(net::OK);
falken 2015/08/28 05:45:24 When trying to trace through this code I found it'
Elly Fong-Jones 2015/08/31 15:03:45 We're actually in STATE_START here. I've added a D
245 return result >= 0 ? net::OK : static_cast<net::Error>(result);
246 }
247
248 net::Error ServiceWorkerCacheWriter::WriteData(
249 net::IOBuffer* buf,
250 size_t buf_size,
251 const OnWriteCompleteCallback& callback) {
252 data_to_write_ = buf;
253 len_to_write_ = buf_size;
254 pending_callback_ = callback;
255 int result = state_machine_.Run(net::OK);
256 return result >= 0 ? net::OK : static_cast<net::Error>(result);
257 }
258
259 size_t ServiceWorkerCacheWriter::BytesWritten() const {
260 return bytes_written_;
261 }
262
263 int ServiceWorkerCacheWriter::Start(int* next_state, bool* pause, int result) {
264 bytes_written_ = 0;
265 compare_reader_ = reader_creator_.Run();
266 if (compare_reader_.get())
267 *next_state = STATE_READ_HEADERS_FOR_COMPARE;
268 else
269 // No existing reader, just write the headers back directly.
270 *next_state = STATE_WRITE_HEADERS_FOR_PASSTHROUGH;
271 return net::OK;
272 }
273
274 int ServiceWorkerCacheWriter::ReadHeadersForCompare(int* next_state,
275 bool* pause,
276 int result) {
277 DCHECK(headers_to_write_);
278
279 headers_to_read_ = new HttpResponseInfoIOBuffer;
280 *next_state = STATE_READ_HEADERS_FOR_COMPARE_DONE;
281 return ReadInfoHelper(compare_reader_, headers_to_read_.get());
282 }
283
284 int ServiceWorkerCacheWriter::ReadHeadersForCompareDone(int* next_state,
285 bool* pause,
286 int result) {
287 if (result < 0) {
288 *next_state = StateMachine::STATE_DONE;
289 return static_cast<int>(result);
290 }
291 cached_length_ = headers_to_read_->response_data_size;
292 net_length_ = headers_to_write_->response_data_size;
293 bytes_compared_ = 0;
294 *pause = true;
295 *next_state = STATE_READ_DATA_FOR_COMPARE;
296 return net::OK;
297 }
298
299 int ServiceWorkerCacheWriter::ReadDataForCompare(int* next_state,
300 bool* pause,
301 int result) {
302 DCHECK(data_to_write_);
303
304 data_to_read_ = new net::IOBuffer(len_to_write_);
305 len_to_read_ = len_to_write_;
306 *next_state = STATE_READ_DATA_FOR_COMPARE_DONE;
307 compare_offset_ = 0;
308 return ReadDataHelper(compare_reader_, data_to_read_.get(), len_to_read_);
309 }
310
311 int ServiceWorkerCacheWriter::ReadDataForCompareDone(int* next_state,
312 bool* pause,
313 int result) {
314 DCHECK(data_to_read_);
315 DCHECK(data_to_write_);
316 DCHECK_EQ(len_to_read_, len_to_write_);
317 DCHECK_LE(result + compare_offset_, static_cast<size_t>(len_to_write_));
318
319 if (result < 0) {
320 *next_state = StateMachine::STATE_DONE;
321 return result;
322 }
323
324 // Premature EOF while reading the AppCache data to compare. Fail the
falken 2015/08/28 05:45:24 I wouldn't call it AppCache data. Service worker h
Elly Fong-Jones 2015/08/31 15:03:45 Done.
325 // comparison.
326 if (result == 0) {
327 *next_state = STATE_READ_HEADERS_FOR_COPY;
328 return net::OK;
329 }
330
331 // Compare the data from AppCache to the data from the network.
332 if (memcmp(data_to_read_->data(), data_to_write_->data() + compare_offset_,
333 result)) {
334 // Data mismatched. This method already validated that all the bytes through
335 // |bytes_compared_| were identical, so copy the first |bytes_compared_|
336 // over, then start writing network data back after the changed point.
337 //
338 // Note that the state machine does NOT get paused here, since there is
339 // still further work to do before this object is ready to handle another
340 // WriteData call.
341 *next_state = STATE_READ_HEADERS_FOR_COPY;
342 return net::OK;
343 }
344
345 compare_offset_ += result;
346
347 // This is a little bit tricky. It is possible that not enough data was read
348 // to finish comparing the entire block of data from the network (which is
349 // kept in len_to_write_), so this method may need to issue another read and
350 // return to this state.
351 //
352 // Compare isn't complete yet. Issue another read for the remaining data. Note
353 // that this reuses the same IOBuffer.
354 if (compare_offset_ < static_cast<size_t>(len_to_read_)) {
355 *next_state = STATE_READ_DATA_FOR_COMPARE_DONE;
356 return ReadDataHelper(compare_reader_, data_to_read_.get(),
357 len_to_read_ - compare_offset_);
358 }
359
360 // Cached entry is longer than the network entry but the prefix matches. Copy
361 // just the prefix.
362 if (bytes_compared_ + compare_offset_ >= net_length_ &&
363 net_length_ < cached_length_) {
364 *next_state = STATE_READ_HEADERS_FOR_COPY;
365 return net::OK;
366 }
367
368 // bytes_compared_ only gets incremented when a full block is compared, to
369 // avoid having to use only parts of the buffered network data.
370 bytes_compared_ += result;
371 *next_state = STATE_READ_DATA_FOR_COMPARE;
372 *pause = true;
373 return net::OK;
374 }
375
376 int ServiceWorkerCacheWriter::WriteHeadersForPassthrough(int* next_state,
377 bool* pause,
378 int result) {
379 writer_ = writer_creator_.Run();
380 *next_state = STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE;
381 return WriteInfoHelper(writer_, headers_to_write_.get());
382 }
383
384 int ServiceWorkerCacheWriter::WriteHeadersForPassthroughDone(int* next_state,
385 bool* pause,
386 int result) {
387 *next_state = STATE_WRITE_DATA_FOR_PASSTHROUGH;
388 *pause = true;
389 return net::OK;
390 }
391
392 int ServiceWorkerCacheWriter::WriteDataForPassthrough(int* next_state,
393 bool* pause,
394 int result) {
395 *next_state = STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE;
396 return WriteDataHelper(writer_, data_to_write_.get(), len_to_write_);
397 }
398
399 int ServiceWorkerCacheWriter::WriteDataForPassthroughDone(int* next_state,
400 bool* pause,
401 int result) {
402 if (result < 0) {
403 *next_state = StateMachine::STATE_DONE;
404 return static_cast<int>(result);
405 }
406 bytes_written_ += result;
407 *next_state = STATE_WRITE_DATA_FOR_PASSTHROUGH;
408 *pause = true;
409 return net::OK;
410 }
411
412 int ServiceWorkerCacheWriter::ReadHeadersForCopy(int* next_state,
413 bool* pause,
414 int result) {
415 bytes_copied_ = 0;
416 copy_reader_ = reader_creator_.Run();
417 headers_to_read_ = new HttpResponseInfoIOBuffer;
418 data_to_copy_ = new net::IOBuffer(kCopyBufferSize);
419 *next_state = STATE_READ_HEADERS_FOR_COPY_DONE;
420 return ReadInfoHelper(copy_reader_, headers_to_read_.get());
421 }
422
423 int ServiceWorkerCacheWriter::ReadHeadersForCopyDone(int* next_state,
424 bool* pause,
425 int result) {
426 if (result < 0) {
427 *next_state = StateMachine::STATE_DONE;
428 return static_cast<int>(result);
429 }
430 *next_state = STATE_WRITE_HEADERS_FOR_COPY;
431 return net::OK;
432 }
433
434 // Write the just-read headers back to the cache.
435 // Note that this method must create |writer_|, since the only paths to this
436 // state never create a writer.
437 // Also note that this *discards* the read headers and replaces them with the
438 // net headers.
439 int ServiceWorkerCacheWriter::WriteHeadersForCopy(int* next_state,
440 bool* pause,
441 int result) {
442 DCHECK(!writer_);
443 writer_ = writer_creator_.Run();
444 *next_state = STATE_WRITE_HEADERS_FOR_COPY_DONE;
445 return WriteInfoHelper(writer_, headers_to_write_.get());
446 }
447
448 int ServiceWorkerCacheWriter::WriteHeadersForCopyDone(int* next_state,
449 bool* pause,
450 int result) {
451 if (result < 0) {
452 *next_state = StateMachine::STATE_DONE;
453 return static_cast<int>(result);
454 }
455 *next_state = STATE_READ_DATA_FOR_COPY;
456 return net::OK;
457 }
458
459 int ServiceWorkerCacheWriter::ReadDataForCopy(int* next_state,
460 bool* pause,
461 int result) {
462 size_t to_read = std::min(kCopyBufferSize, bytes_compared_ - bytes_copied_);
463 // At this point, all compared bytes have been read. Currently
464 // |data_to_write_| and |len_to_write_| hold the chunk of network input that
465 // caused the comparison failure, so those need to be written back and this
466 // object needs to go into passthrough mode.
467 if (to_read == 0) {
468 *next_state = STATE_WRITE_DATA_FOR_PASSTHROUGH;
469 return net::OK;
470 }
471 *next_state = STATE_READ_DATA_FOR_COPY_DONE;
472 return ReadDataHelper(copy_reader_, data_to_copy_.get(), to_read);
473 }
474
475 int ServiceWorkerCacheWriter::ReadDataForCopyDone(int* next_state,
476 bool* pause,
477 int result) {
478 if (result < 0) {
479 *next_state = StateMachine::STATE_DONE;
480 return result;
481 }
482 *next_state = STATE_WRITE_DATA_FOR_COPY;
483 return result;
484 }
485
486 int ServiceWorkerCacheWriter::WriteDataForCopy(int* next_state,
487 bool* pause,
488 int result) {
489 *next_state = STATE_WRITE_DATA_FOR_COPY_DONE;
490 DCHECK_GT(result, 0);
491 return WriteDataHelper(writer_, data_to_copy_.get(), result);
492 }
493
494 int ServiceWorkerCacheWriter::WriteDataForCopyDone(int* next_state,
495 bool* pause,
496 int result) {
497 if (result < 0) {
498 *next_state = StateMachine::STATE_DONE;
499 return result;
500 }
501 bytes_written_ += result;
502 bytes_copied_ += result;
503 *next_state = STATE_READ_DATA_FOR_COPY;
504 return result;
505 }
506
507 int ServiceWorkerCacheWriter::Done(int* next_state, bool* pause, int result) {
508 *next_state = StateMachine::STATE_DONE;
509 return net::OK;
510 }
511
512 // These helpers adapt the AppCache "always use the callback" pattern to the
513 // //net "only use the callback for async" pattern using
514 // AsyncCompletionCallbackAdaptor.
515 //
516 // Specifically, these methods return result codes directly for synchronous
517 // completions, and only run their callback (which is AsyncRunStateMachine) for
518 // asynchronous completions.
519
520 int ServiceWorkerCacheWriter::ReadInfoHelper(
521 const scoped_ptr<ServiceWorkerResponseReader>& reader,
522 HttpResponseInfoIOBuffer* buf) {
523 net::CompletionCallback run_callback =
524 base::Bind(&ServiceWorkerCacheWriter::AsyncRunStateMachine,
525 weak_factory_.GetWeakPtr());
526 scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
527 new AsyncOnlyCompletionCallbackAdaptor(run_callback));
528 reader->ReadInfo(
529 buf, base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
530 adaptor));
531 adaptor->set_async(true);
532 return adaptor->result();
533 }
534
535 int ServiceWorkerCacheWriter::ReadDataHelper(
536 const scoped_ptr<ServiceWorkerResponseReader>& reader,
537 net::IOBuffer* buf,
538 int buf_len) {
539 net::CompletionCallback run_callback =
540 base::Bind(&ServiceWorkerCacheWriter::AsyncRunStateMachine,
541 weak_factory_.GetWeakPtr());
542 scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
543 new AsyncOnlyCompletionCallbackAdaptor(run_callback));
544 reader->ReadData(
545 buf, buf_len,
546 base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
547 adaptor));
548 adaptor->set_async(true);
549 return adaptor->result();
550 }
551
552 int ServiceWorkerCacheWriter::WriteInfoHelper(
553 const scoped_ptr<ServiceWorkerResponseWriter>& writer,
554 HttpResponseInfoIOBuffer* buf) {
555 net::CompletionCallback run_callback =
556 base::Bind(&ServiceWorkerCacheWriter::AsyncRunStateMachine,
557 weak_factory_.GetWeakPtr());
558 scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
559 new AsyncOnlyCompletionCallbackAdaptor(run_callback));
560 writer->WriteInfo(
561 buf, base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
562 adaptor));
563 adaptor->set_async(true);
564 return adaptor->result();
565 }
566
567 int ServiceWorkerCacheWriter::WriteDataHelper(
568 const scoped_ptr<ServiceWorkerResponseWriter>& writer,
569 net::IOBuffer* buf,
570 int buf_len) {
571 net::CompletionCallback run_callback =
572 base::Bind(&ServiceWorkerCacheWriter::AsyncRunStateMachine,
573 weak_factory_.GetWeakPtr());
574 scoped_refptr<AsyncOnlyCompletionCallbackAdaptor> adaptor(
575 new AsyncOnlyCompletionCallbackAdaptor(run_callback));
576 writer->WriteData(
577 buf, buf_len,
578 base::Bind(&AsyncOnlyCompletionCallbackAdaptor::WrappedCallback,
579 adaptor));
580 adaptor->set_async(true);
581 return adaptor->result();
582 }
583
584 void ServiceWorkerCacheWriter::AsyncRunStateMachine(int result) {
585 result = state_machine_.Run(result);
586 // If the result is ERR_IO_PENDING, the pending callback will be run by a
587 // later invocation of AsyncRunStateMachine.
588 if (result != net::ERR_IO_PENDING) {
589 OnWriteCompleteCallback callback = pending_callback_;
590 pending_callback_.Reset();
591 net::Error error = result >= 0 ? net::OK : static_cast<net::Error>(result);
592 callback.Run(error);
593 }
594 }
595
596 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698