| 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..70010c36f57f6312f8f7fa94a87e9e01a2547cb9
|
| --- /dev/null
|
| +++ b/content/browser/service_worker/service_worker_cache_writer.h
|
| @@ -0,0 +1,210 @@
|
| +// 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 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 StateMachine
|
| +// inner class below for the mechanics of 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 |WriteHeaders| and |WriteData|.
|
| + 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|.
|
| + net::Error WriteHeaders(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|.
|
| + net::Error WriteData(net::IOBuffer* buf,
|
| + size_t buf_size,
|
| + const OnWriteCompleteCallback& callback);
|
| +
|
| + // Returns a count of bytes written back to the cache.
|
| + size_t BytesWritten() const;
|
| +
|
| + private:
|
| + // This class provides an abstract state machine with states named by numeric
|
| + // IDs and human-readable string names. Each state has a handler, which is run
|
| + // whenever the state machine is in that state; handlers are responsible for
|
| + // producing the next state for the machine (via the |next_state| argument),
|
| + // deciding whether to pause the state machine (via the |pause| argument), and
|
| + // also generating the next status field, which is passed untouched into the
|
| + // next state's handler.
|
| + class StateMachine {
|
| + public:
|
| + enum {
|
| + // Builtin states. All states are allowed to transition to STATE_DONE and
|
| + // the machine starts in STATE_DONE, but these are otherwise not special.
|
| + STATE_START = -1,
|
| + STATE_DONE = -2,
|
| + };
|
| +
|
| + // The state handler type. The arguments are:
|
| + // int* next_state - state the machine should move to next
|
| + // bool* pause - whether the machine should pause (return from Run) or not
|
| + // int status - status from the previous state's Handler
|
| + using Handler = base::Callback<int(int*, bool*, int)>;
|
| +
|
| + StateMachine();
|
| + ~StateMachine();
|
| +
|
| + // Add a new state to the machine. All states must be registered with this
|
| + // function before transitions are added referencing them. The |name| is an
|
| + // arbitrary string, used only for debugging.
|
| + void AddState(int id, const std::string& name, const Handler& handler);
|
| +
|
| + // Add an allowed transition from state |from_id| to state |to_id|. In debug
|
| + // builds, allowed transitions are enforced by the state machine.
|
| + void AddTransition(int from_id, int to_id);
|
| +
|
| + // In debug builds, DCHECK() that |from_id| and |to_id| are both valid
|
| + // states, and that a transition from |from_id| to |to_id| is allowed.
|
| + void CheckValidTransition(int from_id, int to_id);
|
| +
|
| + // Runs the state machine. This function executes the handlers for
|
| + // successive states of the machine until:
|
| + // a) The machine enters STATE_DONE
|
| + // b) A handler returns a negative value, indicating an error
|
| + // c) A handler pauses the machine
|
| + // This function returns the return value of the last handler that was run.
|
| + int Run(int status);
|
| +
|
| + private:
|
| + // Internal representation of individual states. The |allowed_to| set is a
|
| + // set of states that a machine in this state may transition to.
|
| + struct State {
|
| + State();
|
| + State(int id, const std::string& name, const Handler& handler);
|
| + ~State();
|
| + int id;
|
| + std::string name;
|
| + Handler handler;
|
| + std::set<int> allowed_to;
|
| + };
|
| + std::map<int, State> states_;
|
| + int state_;
|
| + };
|
| +
|
| + // State handlers. See function comments in the corresponding source file for
|
| + // details on these.
|
| + int Start(int* next_state, bool* pause, int result);
|
| + int ReadHeadersForCompare(int* next_state, bool* pause, int result);
|
| + int ReadHeadersForCompareDone(int* next_state, bool* pause, int result);
|
| + int ReadDataForCompare(int* next_state, bool* pause, int result);
|
| + int ReadDataForCompareDone(int* next_state, bool* pause, int result);
|
| + int ReadHeadersForCopy(int* next_state, bool* pause, int result);
|
| + int ReadHeadersForCopyDone(int* next_state, bool* pause, int result);
|
| + int WriteHeadersForCopy(int* next_state, bool* pause, int result);
|
| + int WriteHeadersForCopyDone(int* next_state, bool* pause, int result);
|
| + int ReadDataForCopy(int* next_state, bool* pause, int result);
|
| + int ReadDataForCopyDone(int* next_state, bool* pause, int result);
|
| + int WriteDataForCopy(int* next_state, bool* pause, int result);
|
| + int WriteDataForCopyDone(int* next_state, bool* pause, int result);
|
| + int WriteHeadersForPassthrough(int* next_state, bool* pause, int result);
|
| + int WriteHeadersForPassthroughDone(int* next_state, bool* pause, int result);
|
| + int WriteDataForPassthrough(int* next_state, bool* pause, int result);
|
| + int WriteDataForPassthroughDone(int* next_state, bool* pause, int result);
|
| + int Done(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.
|
| + void AsyncRunStateMachine(int result);
|
| +
|
| + StateMachine state_machine_;
|
| +
|
| + 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 net_length_;
|
| +
|
| + size_t bytes_compared_;
|
| + size_t bytes_copied_;
|
| + size_t bytes_written_;
|
| +
|
| + 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_
|
|
|