Index: content/browser/service_worker/service_worker_cache_writer.h |
diff --git a/content/browser/service_worker/service_worker_cache_writer.h b/content/browser/service_worker/service_worker_cache_writer.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d33020780264bc5e3f88542f27b93ad4510b251a |
--- /dev/null |
+++ b/content/browser/service_worker/service_worker_cache_writer.h |
@@ -0,0 +1,172 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_ |
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_ |
+ |
+#include <map> |
+#include <set> |
+ |
+#include "base/callback.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/memory/weak_ptr.h" |
+#include "net/base/io_buffer.h" |
+#include "net/base/net_errors.h" |
+ |
+namespace content { |
+ |
+struct HttpResponseInfoIOBuffer; |
+class ServiceWorkerCacheWriterCore; |
+class ServiceWorkerResponseReader; |
+class ServiceWorkerResponseWriter; |
+class ServiceWorkerStorage; |
+ |
+// This class is responsible for possibly updating the ServiceWorker script |
+// cache for an installed ServiceWorker main script. If there is no existing |
+// cache entry, this class always writes supplied data back to the cache; if |
+// there is an existing cache entry, this class only writes supplied data back |
+// if there is a cache mismatch. |
+// |
+// Note that writes done by this class cannot be "short" - ie, if they succeed, |
+// they always write all the supplied data back. Therefore completions are |
+// signalled with net::Error without a count of bytes written. |
+// |
+// This class's behavior is modelled as a state machine; see the DoLoop function |
+// for comments about this. |
+class ServiceWorkerCacheWriter { |
+ public: |
+ using OnWriteCompleteCallback = base::Callback<void(net::Error)>; |
+ |
+ // The types for the factory functions passed into the constructor. These are |
+ // responsible for creating readers from the existing cache entry and writers |
+ // to the new cache entry when called. These are passed in as factories |
+ // instead of passing readers and writers in directly to avoid creating |
+ // writers to entries that won't be updated, and because this class may need |
+ // multiple readers internally. |
+ using ResponseReaderCreator = |
+ base::Callback<scoped_ptr<ServiceWorkerResponseReader>(void)>; |
+ using ResponseWriterCreator = |
+ base::Callback<scoped_ptr<ServiceWorkerResponseWriter>(void)>; |
+ |
+ // The existing reader may be null, in which case this instance will |
+ // unconditionally write back data supplied to |MaybeWriteHeaders| and |
+ // |MaybeWriteData|. |
+ ServiceWorkerCacheWriter(const ResponseReaderCreator& reader_creator, |
+ const ResponseWriterCreator& writer_creator); |
+ |
+ virtual ~ServiceWorkerCacheWriter(); |
+ |
+ // Writes the supplied |headers| back to the cache. Returns ERR_IO_PENDING if |
+ // the write will complete asynchronously, in which case |callback| will be |
+ // called when it completes. Otherwise, returns a code other than |
+ // ERR_IO_PENDING and does not invoke |callback|. Note that this method will |
+ // not necessarily write data back to the cache if the incoming data is |
+ // equivalent to the existing cached data. See the source of this function for |
+ // details about how this function drives the state machine. |
+ net::Error MaybeWriteHeaders(HttpResponseInfoIOBuffer* headers, |
+ const OnWriteCompleteCallback& callback); |
+ |
+ // Writes the supplied body data |data| back to the cache. Returns |
+ // ERR_IO_PENDING if the write will complete asynchronously, in which case |
+ // |callback| will be called when it completes. Otherwise, returns a code |
+ // other than ERR_IO_PENDING and does not invoke |callback|. Note that this |
+ // method will not necessarily write data back to the cache if the incoming |
+ // data is equivalent to the existing cached data. See the source of this |
+ // function for details about how this function drives the state machine. |
+ net::Error MaybeWriteData(net::IOBuffer* buf, |
+ size_t buf_size, |
+ const OnWriteCompleteCallback& callback); |
+ |
+ // Returns a count of bytes written back to the cache. |
+ size_t bytes_written() const { return bytes_written_; } |
+ bool did_replace() const { return did_replace_; } |
+ |
+ private: |
+ // Drives this class's state machine. This function steps the state machine |
+ // until one of: |
+ // a) One of the state functions returns an error |
+ // b) One of the state functions pauses the machine |
+ // c) The state machine reaches STATE_DONE |
+ // A successful value (net::OK or greater) indicates that the requested |
+ // operation completed synchronously. A return value of ERR_IO_PENDING |
+ // indicates that some step had to submit asynchronous IO for later |
+ // completion, and the state machine will resume running (via AsyncDoLoop) |
+ // when that asynchronous IO completes. Any other return value indicates that |
+ // the requested operation failed synchronously. |
+ int DoLoop(int result); |
+ |
+ // State handlers. See function comments in the corresponding source file for |
+ // details on these. |
+ int DoStart(int* next_state, bool* pause, int result); |
+ int DoReadHeadersForCompare(int* next_state, bool* pause, int result); |
+ int DoReadHeadersForCompareDone(int* next_state, bool* pause, int result); |
+ int DoReadDataForCompare(int* next_state, bool* pause, int result); |
+ int DoReadDataForCompareDone(int* next_state, bool* pause, int result); |
+ int DoReadHeadersForCopy(int* next_state, bool* pause, int result); |
+ int DoReadHeadersForCopyDone(int* next_state, bool* pause, int result); |
+ int DoWriteHeadersForCopy(int* next_state, bool* pause, int result); |
+ int DoWriteHeadersForCopyDone(int* next_state, bool* pause, int result); |
+ int DoReadDataForCopy(int* next_state, bool* pause, int result); |
+ int DoReadDataForCopyDone(int* next_state, bool* pause, int result); |
+ int DoWriteDataForCopy(int* next_state, bool* pause, int result); |
+ int DoWriteDataForCopyDone(int* next_state, bool* pause, int result); |
+ int DoWriteHeadersForPassthrough(int* next_state, bool* pause, int result); |
+ int DoWriteHeadersForPassthroughDone(int* next_state, |
+ bool* pause, |
+ int result); |
+ int DoWriteDataForPassthrough(int* next_state, bool* pause, int result); |
+ int DoWriteDataForPassthroughDone(int* next_state, bool* pause, int result); |
+ int DoDone(int* next_state, bool* pause, int result); |
+ |
+ // Wrappers for asynchronous calls. These are responsible for scheduling a |
+ // callback to drive the state machine if needed. These either: |
+ // a) Return ERR_IO_PENDING, and schedule a callback to run the state |
+ // machine's Run() later, or |
+ // b) Return some other value and do not schedule a callback. |
+ int ReadInfoHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader, |
+ HttpResponseInfoIOBuffer* buf); |
+ int ReadDataHelper(const scoped_ptr<ServiceWorkerResponseReader>& reader, |
+ net::IOBuffer* buf, |
+ int buf_len); |
+ int WriteInfoHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer, |
+ HttpResponseInfoIOBuffer* buf); |
+ int WriteDataHelper(const scoped_ptr<ServiceWorkerResponseWriter>& writer, |
+ net::IOBuffer* buf, |
+ int buf_len); |
+ |
+ // Callback used by the above helpers. |
Randy Smith (Not in Mondays)
2015/09/13 20:56:36
Suggestion: Include a sentence describing what thi
Elly Fong-Jones
2015/09/15 15:08:24
Done.
|
+ void AsyncDoLoop(int result); |
+ |
+ int state_; |
Randy Smith (Not in Mondays)
2015/09/13 20:56:36
I'd vote in favor of leaving the enum in the heade
Elly Fong-Jones
2015/09/15 15:08:24
Done.
|
+ |
+ scoped_refptr<HttpResponseInfoIOBuffer> headers_to_read_; |
+ scoped_refptr<HttpResponseInfoIOBuffer> headers_to_write_; |
+ scoped_refptr<net::IOBuffer> data_to_read_; |
+ int len_to_read_; |
+ scoped_refptr<net::IOBuffer> data_to_copy_; |
+ scoped_refptr<net::IOBuffer> data_to_write_; |
+ int len_to_write_; |
+ OnWriteCompleteCallback pending_callback_; |
+ |
+ size_t cached_length_; |
+ |
+ size_t bytes_compared_; |
+ size_t bytes_copied_; |
+ size_t bytes_written_; |
+ |
+ bool did_replace_; |
+ |
+ size_t compare_offset_; |
+ |
+ ResponseReaderCreator reader_creator_; |
+ ResponseWriterCreator writer_creator_; |
+ scoped_ptr<ServiceWorkerResponseReader> compare_reader_; |
+ scoped_ptr<ServiceWorkerResponseReader> copy_reader_; |
+ scoped_ptr<ServiceWorkerResponseWriter> writer_; |
+ base::WeakPtrFactory<ServiceWorkerCacheWriter> weak_factory_; |
+}; |
+ |
+} // namespace content |
+ |
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CACHE_WRITER_H_ |