| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2016 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 #ifndef NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_ |
| 6 #define NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_ |
| 7 |
| 8 #include <list> |
| 9 #include <memory> |
| 10 #include "base/memory/weak_ptr.h" |
| 11 #include "net/base/completion_callback.h" |
| 12 #include "net/http/http_cache.h" |
| 13 |
| 14 // Shared reading from the network and writing to the cache enables multiple |
| 15 // HttpCache::Transactions to drive reading the response body from the network. |
| 16 // This ensures that a slow consumer does not starve other consumers of the |
| 17 // same resource. Shared reading/writing starts after the first transaction has |
| 18 // read the response headers. Subsequent transactions are then able to join |
| 19 // reading the response. A shared transaction will either read the already |
| 20 // written part of the response from the cache or invoke read on the network |
| 21 // and write to the cache, depending on its read offset. |
| 22 namespace net { |
| 23 |
| 24 // SharedWriters represents the set of all HttpCache::Transactions that are |
| 25 // reading from the network using the same network transaction and writing to |
| 26 // the same cache entry. It is owned by the ActiveEntry. |
| 27 class HttpCache::SharedWriters { |
| 28 public: |
| 29 // Creates a new SharedWriters object and transfers the ownership of network |
| 30 // transaction to SharedWriters. Consumer must ensure that |*entry| and |
| 31 // |*cache| outlives |this|. It is ok for cache_transaction to die before this |
| 32 // object. |
| 33 static void Create(Transaction* cacheTransaction, |
| 34 std::unique_ptr<HttpTransaction> network_transaction, |
| 35 base::WeakPtr<HttpCache> cache, |
| 36 RequestPriority priority); |
| 37 SharedWriters(base::WeakPtr<HttpCache> cache, |
| 38 ActiveEntry* entry, |
| 39 Transaction* cache_transaction, |
| 40 RequestPriority priority, |
| 41 std::unique_ptr<HttpTransaction> network_transaction); |
| 42 ~SharedWriters(); |
| 43 |
| 44 // Adds a transaction to SharedWriters. Return value is OK if it is the |
| 45 // current validating transaction and ERR_IO_PENDING if it is waiting. |
| 46 int AddTransaction(Transaction* transaction); |
| 47 |
| 48 // Invokes Read on network transaction if a read is not already in progress. |
| 49 // In case a read is already in progress then this transaction is added to |
| 50 // a waiting queue, read_in_progress is set to true and ERR_IO_PENDING is |
| 51 // returned. |
| 52 int Read(scoped_refptr<IOBuffer> buf, |
| 53 int buf_len, |
| 54 const CompletionCallback& callback, |
| 55 Transaction* transaction, |
| 56 bool* read_in_progress); |
| 57 |
| 58 // Invokes WriteData on disk entry. |
| 59 int CacheWrite(scoped_refptr<IOBuffer> buf, |
| 60 int write_len, |
| 61 const CompletionCallback& callback, |
| 62 Transaction* transaction); |
| 63 |
| 64 // Invoked when the validating transaction wants to continue with the entry |
| 65 // as the validation successfully matched it. |
| 66 void OnValidationMatch(Transaction* transaction, RequestPriority priority); |
| 67 |
| 68 // Invoked when the validating transaction cannot continue with the entry as |
| 69 // the validation did not return a 304. Its fine to continue writing to cache |
| 70 // if this is the only transaction, so network transaction ownership is |
| 71 // transferred to SharedWriters. But if there are other transactions, the |
| 72 // entry is doomed and this transaction will continue reading from the |
| 73 // network so the return value will pass the ownership of the network |
| 74 // transaction back to the transaction. |
| 75 std::unique_ptr<HttpTransaction> OnValidationNoMatch( |
| 76 const std::string& key, |
| 77 Transaction* transaction, |
| 78 std::unique_ptr<HttpTransaction> network_transaction, |
| 79 RequestPriority priority); |
| 80 |
| 81 // Invoked when DoneReading is invoked on a shared transaction. The |
| 82 // transaction will be removed from |this|. If another transaction is |
| 83 // currently reading, then other transactions will not be impacted. |
| 84 void DoneReading(Transaction* transaction); |
| 85 |
| 86 // Invoked when StopCaching is called for a shared writer transaction. |
| 87 // It stops caching only if there are no other transactions. |
| 88 void StopCaching(Transaction* transaction); |
| 89 |
| 90 // Removes a transaction which is waiting for Read to be invoked by the |
| 91 // consumer. |
| 92 void RemoveIdleTransaction(Transaction* transaction); |
| 93 |
| 94 // Removes a transaction waiting on a Read call. |
| 95 void RemoveWaitingForReadTransaction(Transaction* transaction); |
| 96 |
| 97 // Removes the currently validating transaction. |
| 98 void RemoveValidatingTransaction(Transaction* transaction); |
| 99 |
| 100 // Removes a pending transaction. |
| 101 bool RemoveWaitingForValidationTransaction(Transaction* transaction); |
| 102 |
| 103 // Removes the currently active transaction. |
| 104 void RemoveActiveTransaction(Transaction* transaction); |
| 105 |
| 106 // Returns true if this object is empty. |
| 107 bool empty(); |
| 108 |
| 109 HttpTransaction* network_transaction() { return network_transaction_.get(); } |
| 110 |
| 111 // Do not add new transactions if in the process of marking the entry as |
| 112 // truncated. |
| 113 bool CanAddNewTransaction(); |
| 114 |
| 115 // Invoked when there is a change in a member transaction's priority or a |
| 116 // member transaction is removed. |
| 117 void PriorityChanged(); |
| 118 |
| 119 private: |
| 120 enum class State { |
| 121 NONE, |
| 122 NETWORK_READ, |
| 123 NETWORK_READ_COMPLETE, |
| 124 CACHE_WRITE_DATA, |
| 125 CACHE_WRITE_DATA_COMPLETE, |
| 126 CACHE_WRITE_TRUNCATED_RESPONSE, |
| 127 CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE, |
| 128 DONE |
| 129 }; |
| 130 |
| 131 // These transactions are waiting on Read. After the active transaction |
| 132 // completes writing the data to the cache, their buffer would be filled with |
| 133 // the data and their callback will be invoked. |
| 134 struct WaitingForRead { |
| 135 Transaction* transaction; |
| 136 scoped_refptr<IOBuffer> read_buf; |
| 137 int read_buf_len; |
| 138 int write_len; |
| 139 const CompletionCallback callback; |
| 140 WaitingForRead(Transaction* transaction, |
| 141 scoped_refptr<IOBuffer> read_buf, |
| 142 int len, |
| 143 const CompletionCallback& consumer_callback); |
| 144 ~WaitingForRead(); |
| 145 WaitingForRead(const WaitingForRead&); |
| 146 }; |
| 147 |
| 148 using WaitingForReadList = std::list<WaitingForRead>; |
| 149 // Runs the state transition loop. Resets and calls |callback_| on exit, |
| 150 // unless the return value is ERR_IO_PENDING. |
| 151 int DoLoop(int result); |
| 152 |
| 153 // State machine functions. |
| 154 int DoNetworkRead(); |
| 155 int DoNetworkReadComplete(int result); |
| 156 int DoCacheWriteData(int num_bytes); |
| 157 int DoCacheWriteDataComplete(int result); |
| 158 int DoCacheWriteTruncatedResponse(); |
| 159 int DoCacheWriteTruncatedResponseComplete(int result); |
| 160 |
| 161 // Helper functions for callback. |
| 162 |
| 163 void OnNetworkReadFailure(int result); |
| 164 |
| 165 bool AttemptTruncation(); |
| 166 |
| 167 void OnCacheWriteSuccess(int result); |
| 168 |
| 169 // Helper function invoked when response is successfully written to the cache. |
| 170 void ResponseDataComplete(); |
| 171 |
| 172 void OnCacheWriteFailure(); |
| 173 |
| 174 void FailureCleanup(int error, bool continue_network_reading); |
| 175 |
| 176 // All pending transactions will not be tracked by entry. |
| 177 void MoveToPendingQueue(); |
| 178 |
| 179 // All transactions eligible for shared writing from entry's pending queue |
| 180 // will be tracked from SharedWriters after this function. |
| 181 void MoveFromPendingQueue(); |
| 182 |
| 183 // When response is completely written, any idle writers are moved to |
| 184 // entry_->readers. |
| 185 void MoveIdleWritersToReaders(); |
| 186 |
| 187 // Posts a task for invoking the io callback of the first transaction waiting |
| 188 // for validation. |
| 189 void ProcessFirstWaitingValidation(); |
| 190 |
| 191 void OnProcessFirstWaitingValidation(); |
| 192 |
| 193 // Notifies the transactions waiting on Read of the result, by posting a task |
| 194 // for each of them. |
| 195 void ProcessWaitingForReadTransactions(int result); |
| 196 |
| 197 // Removes the active transaction from |this|. |
| 198 void ResetActiveTransaction(bool continue_network_reading = false); |
| 199 |
| 200 // Sets the state of idle writers so that they can fail any subsequent |
| 201 // Read. |
| 202 void SetIdleWritersFailState(int result); |
| 203 |
| 204 // Helper function to let the validating transaction continue being a part of |
| 205 // SharedWriters. |
| 206 void ValidationDoneContinue(Transaction* transaction, |
| 207 RequestPriority priority); |
| 208 |
| 209 RequestPriority getCurrentHighestPriority(); |
| 210 |
| 211 // IO Completion callback function. |
| 212 void OnIOComplete(int result); |
| 213 |
| 214 State next_state_ = State::NONE; |
| 215 |
| 216 // Http Cache. |
| 217 base::WeakPtr<HttpCache> cache_; |
| 218 |
| 219 // Owner of this object. |
| 220 ActiveEntry* entry_ = nullptr; |
| 221 |
| 222 std::unique_ptr<HttpTransaction> network_transaction_; |
| 223 |
| 224 scoped_refptr<IOBuffer> read_buf_; |
| 225 int io_buf_len_ = 0; |
| 226 int write_len_ = 0; |
| 227 |
| 228 // The cache transaction that is the current consumer of network_transaction_ |
| 229 // ::Read or writing to the entry and is waiting for the operation to be |
| 230 // completed. This is used to ensure there is at most one consumer. |
| 231 // After the network read and cache write is successful and data |
| 232 // written to cache, other waiting transactions will be notified. |
| 233 Transaction* active_transaction_ = nullptr; |
| 234 |
| 235 // This will point to the currently validating transaction. |
| 236 Transaction* validating_transaction_ = nullptr; |
| 237 |
| 238 // These transactions are waiting for the validating transaction to complete |
| 239 // and then the first of these will begin validation. |
| 240 TransactionList waiting_for_validation_; |
| 241 |
| 242 WaitingForReadList waiting_for_read_; |
| 243 |
| 244 // Includes a transaction if it is past the validation stage. |
| 245 TransactionSet all_writers_; |
| 246 |
| 247 // Current priority of the request. If a higher priority transaction is |
| 248 // added, the priority of network transaction will be increased. |
| 249 RequestPriority priority_ = DEFAULT_PRIORITY; |
| 250 |
| 251 CompletionCallback callback_; // Consumer's callback. |
| 252 base::Callback<void(bool*)> cache_callback_; // Cache callback. |
| 253 CompletionCallback io_callback_; |
| 254 |
| 255 // Saved so it could be returned to the consumer after marking the entry as |
| 256 // truncated, if needed. |
| 257 int rv_post_truncation_ = 0; |
| 258 |
| 259 base::WeakPtrFactory<SharedWriters> weak_factory_; |
| 260 |
| 261 DISALLOW_COPY_AND_ASSIGN(SharedWriters); |
| 262 }; |
| 263 |
| 264 } // namespace net |
| 265 |
| 266 #endif // NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_ |
| OLD | NEW |