Chromium Code Reviews| 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 namespace net { | |
| 15 | |
| 16 class DataAccess; | |
| 17 | |
| 18 // SharedWriters represents the set of all HttpCache::Transactions that are | |
| 19 // reading from the network using the same network transaction and writing to | |
| 20 // the same cache entry. It is owned by the ActiveEntry. | |
| 21 // | |
| 22 // An instance of SharedWriters will be created when the first writer has | |
| 23 // written the new response headers in the cache. | |
| 24 // At creation: | |
| 25 // - The writer’s network transaction’s ownership will be transferred to the new | |
| 26 // DataAccess object owned by SharedWriters and thus can be used by any of the | |
| 27 // HttpCache::Transactions for subsequent reading from the network. | |
| 28 // - The pending_queue will be traversed to see if there are other | |
| 29 // transactions that can be added to SharedWriters. | |
| 30 // | |
| 31 // Destroyed when any of the following happen: | |
| 32 // - All the data has been read from the network and written to cache. | |
| 33 // - ActiveEntry is destroyed. | |
| 34 // - Last transaction part of SharedWriters is destroyed. | |
| 35 // - Response writing is terminated due to a failure. | |
| 36 // - StopCaching API is invoked and caching was successfully stopped. | |
|
Randy Smith (Not in Mondays)
2017/01/19 00:53:43
Suggestion: My model for class documentation is th
shivanisha
2017/01/25 19:46:13
Agree, thanks. Updated the comments in this file t
| |
| 37 class HttpCache::SharedWriters { | |
| 38 public: | |
| 39 // Creates a new SharedWriters object, transfers the ownership of network | |
| 40 // transaction to SharedWriters, and adds the cache transaction to | |
| 41 // all_writers_. | |
| 42 SharedWriters(HttpCache* cache, | |
| 43 ActiveEntry* entry, | |
| 44 Transaction* cache_transaction, | |
| 45 RequestPriority priority, | |
| 46 std::unique_ptr<HttpTransaction> network_transaction); | |
|
Randy Smith (Not in Mondays)
2017/01/19 00:53:43
Recommend documenting lifetimes for raw pointers (
shivanisha
2017/01/25 19:46:13
done.
| |
| 47 ~SharedWriters(); | |
| 48 | |
| 49 // Adds a transaction to SharedWriters. Invokes SetShared on the transaction | |
| 50 // and either assigns the transaction to validating_transaction_ or inserts it | |
| 51 // in waiting_for_validation_. Return value is true if it is the current | |
| 52 // validating_transaction_ and false if its waiting. | |
| 53 bool AddTransaction(Transaction* transaction); | |
| 54 | |
| 55 // Invokes Read on data_access_, assigns this transaction to | |
| 56 // current_writer_ and returns what data_access_->Read() returns. | |
| 57 // In case a read is already in progress then this transaction is instead | |
| 58 // added to waiting_writers_, read_in_progress is set to true and | |
| 59 // ERR_IO_PENDING is returned. | |
| 60 int Read(scoped_refptr<IOBuffer> buf, | |
| 61 int buf_len, | |
| 62 const CompletionCallback& callback, | |
| 63 Transaction* transaction, | |
| 64 bool* read_in_progress); | |
| 65 | |
| 66 // Invokes CacheWrite on data_access_ and returns the return value returned | |
| 67 // from it. Current_writer_ should be equal to transaction. | |
| 68 int CacheWrite(scoped_refptr<IOBuffer> buf, | |
| 69 int write_len, | |
| 70 const CompletionCallback& callback, | |
| 71 Transaction* transaction); | |
| 72 | |
| 73 // Callback to be invoked when validating_transaction_ wants to continue with | |
| 74 // the entry as the validation successfully matched it. | |
| 75 void OnValidationMatch(Transaction* transaction, RequestPriority priority); | |
| 76 | |
| 77 // Callback to be invoked when validating_transaction_ cannot continue with | |
| 78 // the entry as the validation did not return a 304. | |
| 79 // Its ok to continue writing to cache if this is the only transaction in | |
| 80 // SharedWriters, so network_transaction ownership is transferred to | |
| 81 // SharedWriters. But if there are other transactions, entry will be doomed | |
| 82 // and this transaction will continue reading from the network so the return | |
| 83 // value will pass the ownership of the network transaction back to the | |
| 84 // transaction. | |
| 85 std::unique_ptr<HttpTransaction> OnValidationNoMatch( | |
| 86 Transaction* transaction, | |
| 87 std::unique_ptr<HttpTransaction> network_transaction, | |
| 88 RequestPriority priority); | |
| 89 | |
| 90 // Invoked when DoneReading is invoked on a shared transaction. If | |
| 91 // current_writer_ is set, do nothing, else consider it a read completion | |
| 92 // and process accordingly. | |
| 93 void DoneReading(Transaction* transaction); | |
| 94 | |
| 95 // Invoked when StopCaching is called for a shared writer transaction. | |
| 96 // It stops caching only if there are no other transactions in | |
| 97 // all_writers_. | |
| 98 bool StopCaching(Transaction* transaction); | |
| 99 | |
| 100 // Moves all transactions eligible for shared writing from entry's | |
| 101 // pending_queue to waiting_for_validation_. | |
| 102 void MoveFromPendingQueue(); | |
| 103 | |
| 104 // Posts a task for invoking the io callback of the first transaction in | |
| 105 // waiting_for_validation_. | |
| 106 void ProcessFirstWaitingValidation(); | |
| 107 | |
| 108 // Removes a transaction from waiting_for_validation_ and invokes | |
| 109 // ResetShared on it. | |
| 110 bool RemoveWaitingTransaction(Transaction* transaction); | |
| 111 | |
| 112 // Removes a transaction which is in all_writers_ but not currently waiting | |
| 113 // on Read. | |
| 114 void RemoveIdleWriter(Transaction* transaction); | |
| 115 | |
| 116 // Removes a waiting_writer_ transaction. | |
| 117 void RemoveWaitingWriter(Transaction* transaction); | |
| 118 | |
| 119 // Removes the currently validating transaction. | |
| 120 void RemoveValidatingTransaction(Transaction* transaction); | |
| 121 | |
| 122 // Removes the transaction that is currently accessing data_access_. | |
| 123 void RemoveCurrentWriter(Transaction* transaction); | |
| 124 | |
| 125 // Should the owner be able to reset this object? Returns false if | |
| 126 // SharedWriters is in a flow where it is about to destroy itself at the end | |
| 127 // of the flow. | |
| 128 bool CanReset(); | |
| 129 | |
| 130 // Returns true if this object is empty: no transactions in all_writers and | |
| 131 // waiting_for_validation_ and validating_transaction_. | |
| 132 bool empty(); | |
| 133 | |
| 134 friend class Transaction; | |
| 135 | |
| 136 private: | |
| 137 // Runs the state transition loop. Resets and calls |callback_| on exit, | |
| 138 // unless the return value is ERR_IO_PENDING. | |
| 139 int DoLoop(int result); | |
| 140 | |
| 141 // IO Completion callback function. May destroy this object if needed at the | |
| 142 // end of the processing. | |
| 143 void OnIOComplete(int result); | |
| 144 | |
| 145 // State machine functions. | |
| 146 int DoNetworkRead(); | |
| 147 int DoNetworkReadComplete(int result); | |
| 148 int DoCacheWriteData(int num_bytes); | |
| 149 int DoCacheWriteDataComplete(int result); | |
| 150 int DoCacheWriteTruncatedResponse(); | |
| 151 int DoCacheWriteTruncatedResponseComplete(int result); | |
| 152 | |
| 153 // Helper functions for callback. | |
| 154 // | |
| 155 // current_writer_ successfully read from the network. | |
| 156 void OnNetworkReadSuccess(int len); | |
| 157 | |
| 158 // current_writer_ successfully wrote to the cache. | |
| 159 void OnCacheWriteSuccess(int result); | |
| 160 | |
| 161 // current_writer_ fails to write data to the cache. | |
| 162 // It transfers the ownership of data_access_ to the transaction since shared | |
| 163 // writing can no longer continue, but current_writer_ can continue to read | |
| 164 // the remaning data from the network. Any waiting_writers_ will be | |
| 165 // notified of the failure. Any idle transactions or validating_transaction_ | |
| 166 // will be set to a state so that they can fail any subsequent Read calls. | |
| 167 // Any transactions in waiting_for_validation_ will move to pending_queue. | |
| 168 void OnCacheWriteFailure(); | |
| 169 | |
| 170 // current_writer_ fails to read from the network. Both this transaction and | |
| 171 // any waiting_writers_ will return the failure code to their consumers. | |
| 172 // Any idle transactions or validating_transaction_ will be set to a | |
| 173 // state so that they can fail any subsequent Read calls. | |
| 174 // Any transactions in waiting_for_validation_ will move to pending_queue. | |
| 175 // Marking the entry as truncated will be attempted. | |
| 176 void OnNetworkReadFailure(int result); | |
| 177 | |
| 178 // Helper function for doing the cleanup for failure scenarios such as those | |
| 179 // mentioned above. | |
| 180 void FailureCleanup(int error, bool continue_network_reading); | |
| 181 | |
| 182 // Moves all transactions in waiting_for_validation_ to entry's | |
| 183 // pending_queue. | |
| 184 void MoveToPendingQueue(); | |
| 185 | |
| 186 // Notifies the waiting_writers_ of the result, by posting a task for each | |
| 187 // of them. While processing the task for a transaction, it's IO callback | |
| 188 // will be invoked. | |
| 189 void ProcessWaitingWriters(int result); | |
| 190 | |
| 191 // First waiting_for_validation transaction's callback will be invoked. | |
| 192 void OnProcessFirstWaitingValidation(); | |
| 193 | |
| 194 // Removes the current_writer_ transaction from this object. | |
| 195 void ResetCurrentWriter(bool continue_network_reading = false); | |
| 196 | |
| 197 // Sets the state of idle writers so that they can fail any subsequent | |
| 198 // Read. | |
| 199 void SetIdleWritersFailState(int result); | |
| 200 | |
| 201 // When response is completely written, any idle writers are moved to | |
| 202 // entry_->readers. | |
| 203 void MoveIdleWritersToReaders(); | |
| 204 | |
| 205 // Helper function to let the validating_transaction_ continue being a part of | |
| 206 // SharedWriters. | |
| 207 void ValidationDoneContinue(Transaction* transaction, | |
| 208 RequestPriority priority); | |
| 209 | |
| 210 // Helper function invoked when response is successfully written to the cache. | |
| 211 void ResponseDataComplete(); | |
| 212 | |
| 213 // Deletes itself. This is needed for callback scenarios where we no longer | |
| 214 // need shared writing. Entry will release ownership in the flow and | |
| 215 // SharedWriters will delete itself in the end of the flow. | |
| 216 void SelfDestroy(); | |
| 217 | |
| 218 enum State { | |
| 219 STATE_NONE, | |
| 220 STATE_NETWORK_READ, | |
| 221 STATE_NETWORK_READ_COMPLETE, | |
| 222 STATE_CACHE_WRITE_DATA, | |
| 223 STATE_CACHE_WRITE_DATA_COMPLETE, | |
| 224 STATE_CACHE_WRITE_TRUNCATED_RESPONSE, | |
| 225 STATE_CACHE_WRITE_TRUNCATED_RESPONSE_COMPLETE | |
| 226 }; | |
| 227 | |
| 228 State next_state_ = STATE_NONE; | |
|
Randy Smith (Not in Mondays)
2017/01/19 00:53:43
I think it's good to use either all in-declaration
shivanisha
2017/01/25 19:46:13
I have tried to keep all simple initializations he
| |
| 229 | |
| 230 // Http Cache. | |
| 231 base::WeakPtr<HttpCache> cache_; | |
| 232 | |
| 233 // Owner of this object. | |
| 234 ActiveEntry* entry_ = nullptr; | |
| 235 | |
| 236 std::unique_ptr<DataAccess> data_access_; | |
| 237 | |
| 238 scoped_refptr<IOBuffer> read_buf_; | |
| 239 int io_buf_len_ = 0; | |
| 240 int write_len_ = 0; | |
| 241 | |
| 242 // The cache transaction that is the current consumer of data_access_::Read | |
| 243 // or data_access_->CacheWrite and is waiting for the operation to be | |
| 244 // completed. This is used to ensure there is at most one consumer of | |
| 245 // data_access_. After the network read and cache write is successful and data | |
| 246 // written to cache, other waiting writers will be notified. | |
| 247 Transaction* current_writer_ = nullptr; | |
| 248 | |
| 249 // This will point to the currently validating transaction. | |
| 250 // After the validation stage is successfully done, this transaction is | |
| 251 // added to all_writers_. | |
| 252 Transaction* validating_transaction_ = nullptr; | |
| 253 | |
| 254 // If a transaction is currently set in validating_transaction_, these | |
| 255 // transactions will wait for that to complete and then the first of these | |
| 256 // will be assigned to validating_transaction_. | |
| 257 TransactionList waiting_for_validation_; | |
| 258 | |
| 259 // These transactions are waiting on their Read calls when current_writer_ | |
| 260 // is not null. After current_writer_ completes writing the data to the | |
| 261 // cache, their buffer would be filled with the data and their callback | |
| 262 // invoked. | |
| 263 struct WaitingWriter { | |
| 264 Transaction* transaction; | |
| 265 scoped_refptr<IOBuffer> read_buf; | |
| 266 int read_buf_len; | |
| 267 int write_len; | |
| 268 WaitingWriter(Transaction* transaction, | |
| 269 scoped_refptr<IOBuffer> read_buf, | |
| 270 int len); | |
| 271 ~WaitingWriter(); | |
| 272 WaitingWriter(const WaitingWriter&); | |
| 273 }; | |
| 274 typedef std::list<WaitingWriter> WaitingWritersList; | |
| 275 WaitingWritersList waiting_writers_; | |
|
Randy Smith (Not in Mondays)
2017/01/19 00:53:43
Suggestion: I'm finding the reader/writer nomencla
shivanisha
2017/01/20 16:00:09
active_transaction_ and waiting_for_read_ sound go
shivanisha
2017/01/25 19:46:13
Done.
| |
| 276 | |
| 277 // Includes a transaction if it is one of the following: | |
| 278 // 1. current_writer_ or, | |
| 279 // 2. member of waiting_writers_ or, | |
| 280 // 3. Waiting for Read to be invoked from the consumer. | |
| 281 TransactionSet all_writers_; | |
| 282 | |
| 283 // Current priority of the request. If a higher priority transaction is | |
| 284 // added to all_writers_, the priority of data_access_->network_transaction_ | |
| 285 // will be increased. | |
| 286 // todo (shivanisha@): If the higher priority request dies, we do not change | |
| 287 // the priority back to a lower one. Fix this. The priority should be the | |
| 288 // highest of the existing requests. | |
| 289 RequestPriority priority_ = DEFAULT_PRIORITY; | |
| 290 | |
| 291 CompletionCallback callback_; // Consumer's callback. | |
| 292 CompletionCallback io_callback_; | |
| 293 | |
| 294 bool destroy_ = false; // Should be destroyed at the end of this flow. | |
| 295 | |
| 296 // Return value from network read. Saved so it could be returned to the | |
| 297 // consumer after marking the entry as truncated, if needed. | |
| 298 int network_read_rv_ = 0; | |
| 299 | |
| 300 base::WeakPtrFactory<SharedWriters> weak_factory_; | |
| 301 | |
| 302 DISALLOW_COPY_AND_ASSIGN(SharedWriters); | |
| 303 }; | |
| 304 | |
| 305 } // namespace net | |
| 306 | |
| 307 #endif // NET_HTTP_HTTP_CACHE_SHARED_WRITERS_H_ | |
| OLD | NEW |