Chromium Code Reviews| 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..eb97f2e16d43dfb659be313dfc98b2b48315925e |
| --- /dev/null |
| +++ b/net/http/http_cache_shared_writers.h |
| @@ -0,0 +1,255 @@ |
| +// 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" |
| + |
| +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. |
| + SharedWriters(HttpCache* cache, |
| + ActiveEntry* entry, |
| + Transaction* cache_transaction, |
| + RequestPriority priority, |
| + std::unique_ptr<HttpTransaction> network_transaction); |
| + ~SharedWriters(); |
| + |
| + // Adds a transaction to SharedWriters. Return value is true if it is the |
| + // current validating transaction and false if it is waiting. |
| + bool 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, entry |
| + // will be 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); |
| + |
| + // All transactions eligible for shared writing from entry's pending queue |
| + // will be tracked from SharedWriters after this function. |
| + void MoveFromPendingQueue(); |
| + |
| + // Posts a task for invoking the io callback of the first transaction waiting |
| + // for validation. |
| + void ProcessFirstWaitingValidation(); |
| + |
| + // Removes a pending transaction. |
| + bool RemoveWaitingTransaction(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 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: |
| + // Runs the state transition loop. Resets and calls |callback_| on exit, |
| + // unless the return value is ERR_IO_PENDING. |
| + int DoLoop(int result); |
| + |
| + // IO Completion callback function. |
| + void OnIOComplete(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 OnNetworkReadSuccess(int len); |
| + |
| + void OnCacheWriteSuccess(int result); |
| + |
| + void OnCacheWriteFailure(); |
| + |
| + void OnNetworkReadFailure(int result); |
| + |
| + void FailureCleanup(int error, bool continue_network_reading); |
| + |
| + // All pending transactions will not be tracked by entry. |
| + void MoveToPendingQueue(); |
| + |
| + // Notifies the transactions waiting on Read of the result, by posting a task |
| + // for each of them. |
| + void ProcessWaitingForReadTransactions(int result); |
| + |
| + void OnProcessFirstWaitingValidation(); |
| + |
| + // 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); |
| + |
| + // When response is completely written, any idle writers are moved to |
| + // entry_->readers. |
| + void MoveIdleWritersToReaders(); |
| + |
| + // Helper function to let the validating transaction continue being a part of |
| + // SharedWriters. |
| + void ValidationDoneContinue(Transaction* transaction, |
| + RequestPriority priority); |
| + |
| + // Helper function invoked when response is successfully written to the cache. |
| + void ResponseDataComplete(); |
| + |
| + bool AttemptTruncation(); |
| + |
| + RequestPriority getCurrentHighestPriority(); |
| + |
| + enum State { |
|
jkarlin
2017/02/03 18:26:19
The enum declaration should come before the privat
shivanisha
2017/02/06 21:14:10
done
|
| + STATE_NONE, |
| + STATE_NETWORK_READ, |
| + STATE_NETWORK_READ_COMPLETE, |
| + STATE_CACHE_WRITE_DATA, |
| + STATE_CACHE_WRITE_DATA_COMPLETE, |
| + STATE_CACHE_WRITE_TRUNCATED_RESPONSE, |
| + STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE, |
| + STATE_DONE |
| + }; |
| + |
| + 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_; |
| + |
| + // 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 { |
|
jkarlin
2017/02/03 18:26:20
struct should be at beginning of private:
shivanisha
2017/02/06 21:14:10
done
|
| + 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&); |
| + }; |
| + typedef std::list<WaitingForRead> WaitingForReadList; |
|
jkarlin
2017/02/03 18:26:19
using WaitingForReadList = std::list<WaitingForRea
shivanisha
2017/02/06 21:14:10
done
|
| + 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_ |