| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 // This file declares a HttpTransactionFactory implementation that can be |    5 // This file declares a HttpTransactionFactory implementation that can be | 
|    6 // layered on top of another HttpTransactionFactory to add HTTP caching.  The |    6 // layered on top of another HttpTransactionFactory to add HTTP caching.  The | 
|    7 // caching logic follows RFC 7234 (any exceptions are called out in the code). |    7 // caching logic follows RFC 7234 (any exceptions are called out in the code). | 
|    8 // |    8 // | 
|    9 // The HttpCache takes a disk_cache::Backend as a parameter, and uses that for |    9 // The HttpCache takes a disk_cache::Backend as a parameter, and uses that for | 
|   10 // the cache storage. |   10 // the cache storage. | 
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  237   }; |  237   }; | 
|  238  |  238  | 
|  239   class MetadataWriter; |  239   class MetadataWriter; | 
|  240   class QuicServerInfoFactoryAdaptor; |  240   class QuicServerInfoFactoryAdaptor; | 
|  241   class Transaction; |  241   class Transaction; | 
|  242   class WorkItem; |  242   class WorkItem; | 
|  243   friend class Transaction; |  243   friend class Transaction; | 
|  244   friend class ViewCacheHelper; |  244   friend class ViewCacheHelper; | 
|  245   struct PendingOp;  // Info for an entry under construction. |  245   struct PendingOp;  // Info for an entry under construction. | 
|  246  |  246  | 
 |  247   // To help with testing. | 
 |  248   friend class MockHttpCache; | 
 |  249  | 
|  247   using TransactionList = std::list<Transaction*>; |  250   using TransactionList = std::list<Transaction*>; | 
|  248   using TransactionSet = std::unordered_set<Transaction*>; |  251   using TransactionSet = std::unordered_set<Transaction*>; | 
|  249   typedef std::list<std::unique_ptr<WorkItem>> WorkItemList; |  252   typedef std::list<std::unique_ptr<WorkItem>> WorkItemList; | 
|  250  |  253  | 
|  251   struct ActiveEntry { |  254   struct ActiveEntry { | 
|  252     explicit ActiveEntry(disk_cache::Entry* entry); |  255     explicit ActiveEntry(disk_cache::Entry* entry); | 
|  253     ~ActiveEntry(); |  256     ~ActiveEntry(); | 
|  254     size_t EstimateMemoryUsage() const; |  257     size_t EstimateMemoryUsage() const; | 
|  255  |  258  | 
|  256     // Returns true if no transactions are associated with this entry. |  259     // Returns true if no transactions are associated with this entry. | 
|  257     bool HasNoTransactions(); |  260     bool HasNoTransactions(); | 
|  258  |  261  | 
|  259     disk_cache::Entry* disk_entry; |  262     // Returns true if no active readers/writer transactions are associated | 
|  260     Transaction*       writer; |  263     // with this entry. | 
 |  264     bool HasNoActiveTransactions(); | 
 |  265  | 
 |  266     disk_cache::Entry* disk_entry = nullptr; | 
 |  267  | 
 |  268     // We implement a basic reader/writer lock for the disk cache entry. If | 
 |  269     // there is a writer, then all read-only transactions must wait. Non | 
 |  270     // read-only transactions can proceed to their validation phase. Validation | 
 |  271     // is allowed for one transaction at a time so that we do not end up with | 
 |  272     // wasted network requests. | 
 |  273  | 
 |  274     // The following variables represent the various transactions associated | 
 |  275     // with this entry in different stages. A transaction goes through these | 
 |  276     // transitions. | 
 |  277     // | 
 |  278     // Write mode transactions: | 
 |  279     // add_to_entry_queue-> headers_transaction -> done_headers_queue -> | 
 |  280     // writer | 
 |  281     // add_to_entry_queue-> headers_transaction -> done_headers_queue -> | 
 |  282     // readers (once the data is written to the cache by another writer) | 
 |  283     // | 
 |  284     // Read only transactions: | 
 |  285     // add_to_entry_queue-> readers (once the data is written to the cache by | 
 |  286     // the writer) | 
 |  287  | 
 |  288     // Transactions waiting to be added to entry. | 
 |  289     TransactionList add_to_entry_queue; | 
 |  290  | 
 |  291     // Transaction currently in the headers phase, either validating the | 
 |  292     // response or getting new headers. This can exist simultaneously with | 
 |  293     // writer or readers while validating existing headers. | 
 |  294     Transaction* headers_transaction = nullptr; | 
 |  295  | 
 |  296     // Transactions that have completed their headers phase and are waiting | 
 |  297     // to read the response body or write the response body. | 
 |  298     TransactionList done_headers_queue; | 
 |  299  | 
 |  300     // Transaction currently reading from the network and writing to the cache. | 
 |  301     Transaction* writer = nullptr; | 
 |  302  | 
 |  303     // Transactions that can only read from the cache. Only one of writer or | 
 |  304     // readers can exist at a time. | 
|  261     TransactionSet readers; |  305     TransactionSet readers; | 
|  262     TransactionList    pending_queue; |  306  | 
|  263     bool               will_process_pending_queue; |  307     // The following variables are true if OnProcessQueuedTransactions is posted | 
|  264     bool               doomed; |  308     bool will_process_queued_transactions = false; | 
 |  309  | 
 |  310     // True if entry is doomed. | 
 |  311     bool doomed = false; | 
|  265   }; |  312   }; | 
|  266  |  313  | 
|  267   using ActiveEntriesMap = |  314   using ActiveEntriesMap = | 
|  268       std::unordered_map<std::string, std::unique_ptr<ActiveEntry>>; |  315       std::unordered_map<std::string, std::unique_ptr<ActiveEntry>>; | 
|  269   using PendingOpsMap = std::unordered_map<std::string, PendingOp*>; |  316   using PendingOpsMap = std::unordered_map<std::string, PendingOp*>; | 
|  270   using ActiveEntriesSet = std::map<ActiveEntry*, std::unique_ptr<ActiveEntry>>; |  317   using ActiveEntriesSet = std::map<ActiveEntry*, std::unique_ptr<ActiveEntry>>; | 
|  271   using PlaybackCacheMap = std::unordered_map<std::string, int>; |  318   using PlaybackCacheMap = std::unordered_map<std::string, int>; | 
|  272  |  319  | 
|  273   // Methods ------------------------------------------------------------------ |  320   // Methods ------------------------------------------------------------------ | 
|  274  |  321  | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  335  |  382  | 
|  336   // Creates the disk cache entry associated with |key|, returning an |  383   // Creates the disk cache entry associated with |key|, returning an | 
|  337   // ActiveEntry in |*entry|. |trans| will be notified via its IO callback if |  384   // ActiveEntry in |*entry|. |trans| will be notified via its IO callback if | 
|  338   // this method returns ERR_IO_PENDING. |  385   // this method returns ERR_IO_PENDING. | 
|  339   int CreateEntry(const std::string& key, ActiveEntry** entry, |  386   int CreateEntry(const std::string& key, ActiveEntry** entry, | 
|  340                   Transaction* trans); |  387                   Transaction* trans); | 
|  341  |  388  | 
|  342   // Destroys an ActiveEntry (active or doomed). |  389   // Destroys an ActiveEntry (active or doomed). | 
|  343   void DestroyEntry(ActiveEntry* entry); |  390   void DestroyEntry(ActiveEntry* entry); | 
|  344  |  391  | 
|  345   // Adds a transaction to an ActiveEntry. If this method returns ERR_IO_PENDING |  392   // Adds a transaction to an ActiveEntry. This method returns ERR_IO_PENDING | 
|  346   // the transaction will be notified about completion via its IO callback. This |  393   // and the transaction will be notified about completion via its IO callback. | 
|  347   // method returns ERR_CACHE_RACE to signal the transaction that it cannot be |  394   int AddTransactionToEntry(ActiveEntry* entry, Transaction* transaction); | 
|  348   // added to the provided entry, and it should retry the process with another |  395  | 
|  349   // one (in this case, the entry is no longer valid). |  396   // Transaction invokes this when its response headers phase is complete | 
|  350   int AddTransactionToEntry(ActiveEntry* entry, Transaction* trans); |  397   // either on validating existing headers/skipping validation or getting new | 
 |  398   // headers. The transaction is added to a queue and a task is posted | 
 |  399   // to process queued transactions of the entry. Returns ERR_IO_PENDING. | 
 |  400   int DoneWithResponseHeaders(ActiveEntry* entry, Transaction* transaction); | 
|  351  |  401  | 
|  352   // Called when the transaction has finished working with this entry. |cancel| |  402   // Called when the transaction has finished working with this entry. |cancel| | 
|  353   // is true if the operation was cancelled by the caller instead of running |  403   // is true if the operation was cancelled by the caller instead of running | 
|  354   // to completion. |  404   // to completion. | 
|  355   void DoneWithEntry(ActiveEntry* entry, Transaction* trans, bool cancel); |  405   void DoneWithEntry(ActiveEntry* entry, Transaction* transaction, bool cancel); | 
 |  406  | 
 |  407   // Returns true if this transaction is currently writing or about to start | 
 |  408   // writing the response body. | 
 |  409   bool IsTransactionCurrentOrFutureWriter(ActiveEntry* entry, | 
 |  410                                           Transaction* transaction, | 
 |  411                                           const std::string& method) const; | 
|  356  |  412  | 
|  357   // Called when the transaction has finished writing to this entry. |success| |  413   // Called when the transaction has finished writing to this entry. |success| | 
|  358   // is false if the cache entry should be deleted. |  414   // is false if the cache entry should be deleted. | 
|  359   void DoneWritingToEntry(ActiveEntry* entry, bool success); |  415   void DoneWritingToEntry(ActiveEntry* entry, | 
 |  416                           bool success, | 
 |  417                           Transaction* transaction); | 
|  360  |  418  | 
|  361   // Called when the transaction has finished reading from this entry. |  419   // Called when the transaction has finished reading from this entry. | 
|  362   void DoneReadingFromEntry(ActiveEntry* entry, Transaction* trans); |  420   void DoneReadingFromEntry(ActiveEntry* entry, Transaction* transaction); | 
|  363  |  | 
|  364   // Converts the active writer transaction to a reader so that other |  | 
|  365   // transactions can start reading from this entry. |  | 
|  366   void ConvertWriterToReader(ActiveEntry* entry); |  | 
|  367  |  421  | 
|  368   // Returns the LoadState of the provided pending transaction. |  422   // Returns the LoadState of the provided pending transaction. | 
|  369   LoadState GetLoadStateForPendingTransaction(const Transaction* trans); |  423   LoadState GetLoadStateForPendingTransaction(const Transaction* trans); | 
|  370  |  424  | 
|  371   // Removes the transaction |trans|, from the pending list of an entry |  425   // Removes the transaction |trans|, from the pending list of an entry | 
|  372   // (PendingOp, active or doomed entry). |  426   // (PendingOp, active or doomed entry). | 
|  373   void RemovePendingTransaction(Transaction* trans); |  427   void RemovePendingTransaction(Transaction* trans); | 
|  374  |  428  | 
|  375   // Removes the transaction |trans|, from the pending list of |entry|. |  429   // Removes the transaction |trans|, from the pending list of |entry|. | 
|  376   bool RemovePendingTransactionFromEntry(ActiveEntry* entry, |  430   bool RemovePendingTransactionFromEntry(ActiveEntry* entry, | 
|  377                                          Transaction* trans); |  431                                          Transaction* trans); | 
|  378  |  432  | 
|  379   // Removes the transaction |trans|, from the pending list of |pending_op|. |  433   // Removes the transaction |trans|, from the pending list of |pending_op|. | 
|  380   bool RemovePendingTransactionFromPendingOp(PendingOp* pending_op, |  434   bool RemovePendingTransactionFromPendingOp(PendingOp* pending_op, | 
|  381                                              Transaction* trans); |  435                                              Transaction* trans); | 
|  382   // Resumes processing the pending list of |entry|. |  436  | 
|  383   void ProcessPendingQueue(ActiveEntry* entry); |  437   // Removes and returns all queued transactions in |entry| in FIFO order. This | 
 |  438   // includes transactions that have completed the headers phase and those that | 
 |  439   // have not been added to the entry yet in that order. |list| is the output | 
 |  440   // argument. | 
 |  441   void RemoveAllQueuedTransactions(ActiveEntry* entry, TransactionList* list); | 
 |  442  | 
 |  443   // Resumes processing the queued transactions of |entry|. | 
 |  444   void ProcessQueuedTransactions(ActiveEntry* entry); | 
 |  445  | 
 |  446   // Checks if a transaction can be added to the entry. If yes, it will | 
 |  447   // invoke the IO callback of the transaction. This is a helper function for | 
 |  448   // OnProcessQueuedTransactions. | 
 |  449   void ProcessAddToEntryQueue(ActiveEntry* entry); | 
 |  450  | 
 |  451   // Checks if a transaction that has already completed the response headers | 
 |  452   // phase can resume reading/writing the response body. If yes, it will | 
 |  453   // invoke the IO callback of the transaction. This is a helper function for | 
 |  454   // OnProcessQueuedTransactions. | 
 |  455   void ProcessDoneHeadersQueue(ActiveEntry* entry); | 
 |  456  | 
 |  457   // Processes either writer's failure to write response body or | 
 |  458   // headers_transactions's failure to write headers. | 
 |  459   void ProcessEntryFailure(ActiveEntry* entry); | 
|  384  |  460  | 
|  385   // Events (called via PostTask) --------------------------------------------- |  461   // Events (called via PostTask) --------------------------------------------- | 
|  386  |  462  | 
|  387   void OnProcessPendingQueue(ActiveEntry* entry); |  463   void OnProcessQueuedTransactions(ActiveEntry* entry); | 
|  388  |  464  | 
|  389   // Callbacks ---------------------------------------------------------------- |  465   // Callbacks ---------------------------------------------------------------- | 
|  390  |  466  | 
|  391   // Processes BackendCallback notifications. |  467   // Processes BackendCallback notifications. | 
|  392   void OnIOComplete(int result, PendingOp* entry); |  468   void OnIOComplete(int result, PendingOp* entry); | 
|  393  |  469  | 
|  394   // Helper to conditionally delete |pending_op| if the HttpCache object it |  470   // Helper to conditionally delete |pending_op| if the HttpCache object it | 
|  395   // is meant for has been deleted. |  471   // is meant for has been deleted. | 
|  396   // |  472   // | 
|  397   // TODO(ajwong): The PendingOp lifetime management is very tricky.  It might |  473   // TODO(ajwong): The PendingOp lifetime management is very tricky.  It might | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  435   std::unique_ptr<base::Clock> clock_; |  511   std::unique_ptr<base::Clock> clock_; | 
|  436  |  512  | 
|  437   base::WeakPtrFactory<HttpCache> weak_factory_; |  513   base::WeakPtrFactory<HttpCache> weak_factory_; | 
|  438  |  514  | 
|  439   DISALLOW_COPY_AND_ASSIGN(HttpCache); |  515   DISALLOW_COPY_AND_ASSIGN(HttpCache); | 
|  440 }; |  516 }; | 
|  441  |  517  | 
|  442 }  // namespace net |  518 }  // namespace net | 
|  443  |  519  | 
|  444 #endif  // NET_HTTP_HTTP_CACHE_H_ |  520 #endif  // NET_HTTP_HTTP_CACHE_H_ | 
| OLD | NEW |