| Index: net/http/http_cache_shared_writers.h
|
| diff --git a/net/http/http_cache_shared_writers.h b/net/http/http_cache_shared_writers.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..84652dde48d8ce2899bd1a6607ca3e6706ff61ee
|
| --- /dev/null
|
| +++ b/net/http/http_cache_shared_writers.h
|
| @@ -0,0 +1,266 @@
|
| +// Copyright (c) 2016 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 NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_
|
| +#define NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_
|
| +
|
| +#include <list>
|
| +#include <memory>
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "net/base/completion_callback.h"
|
| +#include "net/http/http_cache.h"
|
| +
|
| +// Shared reading from the network and writing to the cache enables multiple
|
| +// HttpCache::Transactions to drive reading the response body from the network.
|
| +// This ensures that a slow consumer does not starve other consumers of the
|
| +// same resource. Shared reading/writing starts after the first transaction has
|
| +// read the response headers. Subsequent transactions are then able to join
|
| +// reading the response. A shared transaction will either read the already
|
| +// written part of the response from the cache or invoke read on the network
|
| +// and write to the cache, depending on its read offset.
|
| +namespace net {
|
| +
|
| +// SharedWriters represents the set of all HttpCache::Transactions that are
|
| +// reading from the network using the same network transaction and writing to
|
| +// the same cache entry. It is owned by the ActiveEntry.
|
| +class HttpCache::SharedWriters {
|
| + public:
|
| + // Creates a new SharedWriters object and transfers the ownership of network
|
| + // transaction to SharedWriters. Consumer must ensure that |*entry| and
|
| + // |*cache| outlives |this|. It is ok for cache_transaction to die before this
|
| + // object.
|
| + static void Create(Transaction* cacheTransaction,
|
| + std::unique_ptr<HttpTransaction> network_transaction,
|
| + base::WeakPtr<HttpCache> cache,
|
| + RequestPriority priority);
|
| + SharedWriters(base::WeakPtr<HttpCache> cache,
|
| + ActiveEntry* entry,
|
| + Transaction* cache_transaction,
|
| + RequestPriority priority,
|
| + std::unique_ptr<HttpTransaction> network_transaction);
|
| + ~SharedWriters();
|
| +
|
| + // Adds a transaction to SharedWriters. Return value is OK if it is the
|
| + // current validating transaction and ERR_IO_PENDING if it is waiting.
|
| + int AddTransaction(Transaction* transaction);
|
| +
|
| + // Invokes Read on network transaction if a read is not already in progress.
|
| + // In case a read is already in progress then this transaction is added to
|
| + // a waiting queue, read_in_progress is set to true and ERR_IO_PENDING is
|
| + // returned.
|
| + int Read(scoped_refptr<IOBuffer> buf,
|
| + int buf_len,
|
| + const CompletionCallback& callback,
|
| + Transaction* transaction,
|
| + bool* read_in_progress);
|
| +
|
| + // Invokes WriteData on disk entry.
|
| + int CacheWrite(scoped_refptr<IOBuffer> buf,
|
| + int write_len,
|
| + const CompletionCallback& callback,
|
| + Transaction* transaction);
|
| +
|
| + // Invoked when the validating transaction wants to continue with the entry
|
| + // as the validation successfully matched it.
|
| + void OnValidationMatch(Transaction* transaction, RequestPriority priority);
|
| +
|
| + // Invoked when the validating transaction cannot continue with the entry as
|
| + // the validation did not return a 304. Its fine to continue writing to cache
|
| + // if this is the only transaction, so network transaction ownership is
|
| + // transferred to SharedWriters. But if there are other transactions, the
|
| + // entry is doomed and this transaction will continue reading from the
|
| + // network so the return value will pass the ownership of the network
|
| + // transaction back to the transaction.
|
| + std::unique_ptr<HttpTransaction> OnValidationNoMatch(
|
| + const std::string& key,
|
| + Transaction* transaction,
|
| + std::unique_ptr<HttpTransaction> network_transaction,
|
| + RequestPriority priority);
|
| +
|
| + // Invoked when DoneReading is invoked on a shared transaction. The
|
| + // transaction will be removed from |this|. If another transaction is
|
| + // currently reading, then other transactions will not be impacted.
|
| + void DoneReading(Transaction* transaction);
|
| +
|
| + // Invoked when StopCaching is called for a shared writer transaction.
|
| + // It stops caching only if there are no other transactions.
|
| + void StopCaching(Transaction* transaction);
|
| +
|
| + // Removes a transaction which is waiting for Read to be invoked by the
|
| + // consumer.
|
| + void RemoveIdleTransaction(Transaction* transaction);
|
| +
|
| + // Removes a transaction waiting on a Read call.
|
| + void RemoveWaitingForReadTransaction(Transaction* transaction);
|
| +
|
| + // Removes the currently validating transaction.
|
| + void RemoveValidatingTransaction(Transaction* transaction);
|
| +
|
| + // Removes a pending transaction.
|
| + bool RemoveWaitingForValidationTransaction(Transaction* transaction);
|
| +
|
| + // Removes the currently active transaction.
|
| + void RemoveActiveTransaction(Transaction* transaction);
|
| +
|
| + // Returns true if this object is empty.
|
| + bool empty();
|
| +
|
| + HttpTransaction* network_transaction() { return network_transaction_.get(); }
|
| +
|
| + // Do not add new transactions if in the process of marking the entry as
|
| + // truncated.
|
| + bool CanAddNewTransaction();
|
| +
|
| + // Invoked when there is a change in a member transaction's priority or a
|
| + // member transaction is removed.
|
| + void PriorityChanged();
|
| +
|
| + private:
|
| + enum class State {
|
| + NONE,
|
| + NETWORK_READ,
|
| + NETWORK_READ_COMPLETE,
|
| + CACHE_WRITE_DATA,
|
| + CACHE_WRITE_DATA_COMPLETE,
|
| + CACHE_WRITE_TRUNCATED_RESPONSE,
|
| + CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE,
|
| + DONE
|
| + };
|
| +
|
| + // These transactions are waiting on Read. After the active transaction
|
| + // completes writing the data to the cache, their buffer would be filled with
|
| + // the data and their callback will be invoked.
|
| + struct WaitingForRead {
|
| + Transaction* transaction;
|
| + scoped_refptr<IOBuffer> read_buf;
|
| + int read_buf_len;
|
| + int write_len;
|
| + const CompletionCallback callback;
|
| + WaitingForRead(Transaction* transaction,
|
| + scoped_refptr<IOBuffer> read_buf,
|
| + int len,
|
| + const CompletionCallback& consumer_callback);
|
| + ~WaitingForRead();
|
| + WaitingForRead(const WaitingForRead&);
|
| + };
|
| +
|
| + using WaitingForReadList = std::list<WaitingForRead>;
|
| + // Runs the state transition loop. Resets and calls |callback_| on exit,
|
| + // unless the return value is ERR_IO_PENDING.
|
| + int DoLoop(int result);
|
| +
|
| + // State machine functions.
|
| + int DoNetworkRead();
|
| + int DoNetworkReadComplete(int result);
|
| + int DoCacheWriteData(int num_bytes);
|
| + int DoCacheWriteDataComplete(int result);
|
| + int DoCacheWriteTruncatedResponse();
|
| + int DoCacheWriteTruncatedResponseComplete(int result);
|
| +
|
| + // Helper functions for callback.
|
| +
|
| + void OnNetworkReadFailure(int result);
|
| +
|
| + bool AttemptTruncation();
|
| +
|
| + void OnCacheWriteSuccess(int result);
|
| +
|
| + // Helper function invoked when response is successfully written to the cache.
|
| + void ResponseDataComplete();
|
| +
|
| + void OnCacheWriteFailure();
|
| +
|
| + void FailureCleanup(int error, bool continue_network_reading);
|
| +
|
| + // All pending transactions will not be tracked by entry.
|
| + void MoveToPendingQueue();
|
| +
|
| + // All transactions eligible for shared writing from entry's pending queue
|
| + // will be tracked from SharedWriters after this function.
|
| + void MoveFromPendingQueue();
|
| +
|
| + // When response is completely written, any idle writers are moved to
|
| + // entry_->readers.
|
| + void MoveIdleWritersToReaders();
|
| +
|
| + // Posts a task for invoking the io callback of the first transaction waiting
|
| + // for validation.
|
| + void ProcessFirstWaitingValidation();
|
| +
|
| + void OnProcessFirstWaitingValidation();
|
| +
|
| + // Notifies the transactions waiting on Read of the result, by posting a task
|
| + // for each of them.
|
| + void ProcessWaitingForReadTransactions(int result);
|
| +
|
| + // Removes the active transaction from |this|.
|
| + void ResetActiveTransaction(bool continue_network_reading = false);
|
| +
|
| + // Sets the state of idle writers so that they can fail any subsequent
|
| + // Read.
|
| + void SetIdleWritersFailState(int result);
|
| +
|
| + // Helper function to let the validating transaction continue being a part of
|
| + // SharedWriters.
|
| + void ValidationDoneContinue(Transaction* transaction,
|
| + RequestPriority priority);
|
| +
|
| + RequestPriority getCurrentHighestPriority();
|
| +
|
| + // IO Completion callback function.
|
| + void OnIOComplete(int result);
|
| +
|
| + State next_state_ = State::NONE;
|
| +
|
| + // Http Cache.
|
| + base::WeakPtr<HttpCache> cache_;
|
| +
|
| + // Owner of this object.
|
| + ActiveEntry* entry_ = nullptr;
|
| +
|
| + std::unique_ptr<HttpTransaction> network_transaction_;
|
| +
|
| + scoped_refptr<IOBuffer> read_buf_;
|
| + int io_buf_len_ = 0;
|
| + int write_len_ = 0;
|
| +
|
| + // The cache transaction that is the current consumer of network_transaction_
|
| + // ::Read or writing to the entry and is waiting for the operation to be
|
| + // completed. This is used to ensure there is at most one consumer.
|
| + // After the network read and cache write is successful and data
|
| + // written to cache, other waiting transactions will be notified.
|
| + Transaction* active_transaction_ = nullptr;
|
| +
|
| + // This will point to the currently validating transaction.
|
| + Transaction* validating_transaction_ = nullptr;
|
| +
|
| + // These transactions are waiting for the validating transaction to complete
|
| + // and then the first of these will begin validation.
|
| + TransactionList waiting_for_validation_;
|
| +
|
| + WaitingForReadList waiting_for_read_;
|
| +
|
| + // Includes a transaction if it is past the validation stage.
|
| + TransactionSet all_writers_;
|
| +
|
| + // Current priority of the request. If a higher priority transaction is
|
| + // added, the priority of network transaction will be increased.
|
| + RequestPriority priority_ = DEFAULT_PRIORITY;
|
| +
|
| + CompletionCallback callback_; // Consumer's callback.
|
| + base::Callback<void(bool*)> cache_callback_; // Cache callback.
|
| + CompletionCallback io_callback_;
|
| +
|
| + // Saved so it could be returned to the consumer after marking the entry as
|
| + // truncated, if needed.
|
| + int rv_post_truncation_ = 0;
|
| +
|
| + base::WeakPtrFactory<SharedWriters> weak_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SharedWriters);
|
| +};
|
| +
|
| +} // namespace net
|
| +
|
| +#endif // NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_
|
|
|