simple_entry_impl.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. // Copyright (c) 2013 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. #ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
  5. #define NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include <string>
  9. #include "base/containers/queue.h"
  10. #include "base/files/file_path.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/memory/ref_counted.h"
  13. #include "base/sequence_checker.h"
  14. #include "base/time/time.h"
  15. #include "net/base/cache_type.h"
  16. #include "net/base/net_export.h"
  17. #include "net/base/request_priority.h"
  18. #include "net/disk_cache/disk_cache.h"
  19. #include "net/disk_cache/simple/post_doom_waiter.h"
  20. #include "net/disk_cache/simple/simple_entry_format.h"
  21. #include "net/disk_cache/simple/simple_entry_operation.h"
  22. #include "net/disk_cache/simple/simple_synchronous_entry.h"
  23. #include "net/log/net_log_event_type.h"
  24. #include "net/log/net_log_with_source.h"
  25. namespace base {
  26. class TaskRunner;
  27. }
  28. namespace net {
  29. class GrowableIOBuffer;
  30. class IOBuffer;
  31. class NetLog;
  32. class PrioritizedTaskRunner;
  33. }
  34. namespace disk_cache {
  35. class BackendCleanupTracker;
  36. class SimpleBackendImpl;
  37. class SimpleEntryStat;
  38. class SimpleFileTracker;
  39. class SimpleSynchronousEntry;
  40. struct SimpleEntryCreationResults;
  41. // SimpleEntryImpl is the source task_runner interface to an entry in the very
  42. // simple disk cache. It proxies for the SimpleSynchronousEntry, which performs
  43. // IO on the worker thread.
  44. class NET_EXPORT_PRIVATE SimpleEntryImpl : public Entry,
  45. public base::RefCounted<SimpleEntryImpl> {
  46. friend class base::RefCounted<SimpleEntryImpl>;
  47. public:
  48. enum OperationsMode {
  49. NON_OPTIMISTIC_OPERATIONS,
  50. OPTIMISTIC_OPERATIONS,
  51. };
  52. // The Backend provides an |ActiveEntryProxy| instance to this entry when it
  53. // is active, meaning it's the canonical entry for this |entry_hash_|. The
  54. // entry can make itself inactive by deleting its proxy.
  55. class ActiveEntryProxy {
  56. public:
  57. virtual ~ActiveEntryProxy() = 0;
  58. };
  59. SimpleEntryImpl(
  60. net::CacheType cache_type,
  61. const base::FilePath& path,
  62. scoped_refptr<BackendCleanupTracker> cleanup_tracker,
  63. uint64_t entry_hash,
  64. OperationsMode operations_mode,
  65. SimpleBackendImpl* backend,
  66. SimpleFileTracker* file_tracker,
  67. scoped_refptr<BackendFileOperationsFactory> file_operations_factory,
  68. net::NetLog* net_log,
  69. uint32_t entry_priority);
  70. void SetActiveEntryProxy(
  71. std::unique_ptr<ActiveEntryProxy> active_entry_proxy);
  72. // Adds another reader/writer to this entry, if possible.
  73. EntryResult OpenEntry(EntryResultCallback callback);
  74. // Creates this entry, if possible.
  75. EntryResult CreateEntry(EntryResultCallback callback);
  76. // Opens an existing entry or creates a new one.
  77. EntryResult OpenOrCreateEntry(EntryResultCallback callback);
  78. // Identical to Backend::Doom() except that it accepts a
  79. // CompletionOnceCallback.
  80. net::Error DoomEntry(CompletionOnceCallback callback);
  81. const std::string& key() const { return key_; }
  82. uint64_t entry_hash() const { return entry_hash_; }
  83. // The key is not a constructor parameter to the SimpleEntryImpl, because
  84. // during cache iteration, it's necessary to open entries by their hash
  85. // alone. In that case, the SimpleSynchronousEntry will read the key from disk
  86. // and it will be set.
  87. void SetKey(const std::string& key);
  88. // SetCreatePendingDoom() should be called before CreateEntry() if the
  89. // creation should suceed optimistically but not do any I/O until
  90. // NotifyDoomBeforeCreateComplete() is called.
  91. void SetCreatePendingDoom();
  92. void NotifyDoomBeforeCreateComplete();
  93. // From Entry:
  94. void Doom() override;
  95. void Close() override;
  96. std::string GetKey() const override;
  97. // GetLastUsed() should not be called in net::APP_CACHE mode since the times
  98. // are not updated.
  99. base::Time GetLastUsed() const override;
  100. base::Time GetLastModified() const override;
  101. int32_t GetDataSize(int index) const override;
  102. int ReadData(int stream_index,
  103. int offset,
  104. net::IOBuffer* buf,
  105. int buf_len,
  106. CompletionOnceCallback callback) override;
  107. int WriteData(int stream_index,
  108. int offset,
  109. net::IOBuffer* buf,
  110. int buf_len,
  111. CompletionOnceCallback callback,
  112. bool truncate) override;
  113. int ReadSparseData(int64_t offset,
  114. net::IOBuffer* buf,
  115. int buf_len,
  116. CompletionOnceCallback callback) override;
  117. int WriteSparseData(int64_t offset,
  118. net::IOBuffer* buf,
  119. int buf_len,
  120. CompletionOnceCallback callback) override;
  121. RangeResult GetAvailableRange(int64_t offset,
  122. int len,
  123. RangeResultCallback callback) override;
  124. bool CouldBeSparse() const override;
  125. void CancelSparseIO() override;
  126. net::Error ReadyForSparseIO(CompletionOnceCallback callback) override;
  127. void SetLastUsedTimeForTest(base::Time time) override;
  128. // Changes the entry's priority in its TaskRunner.
  129. void SetPriority(uint32_t entry_priority);
  130. private:
  131. class ScopedOperationRunner;
  132. friend class ScopedOperationRunner;
  133. enum State {
  134. // The state immediately after construction, but before |synchronous_entry_|
  135. // has been assigned. This is the state at construction, and is one of the
  136. // two states (along with failure) one can destruct an entry in.
  137. STATE_UNINITIALIZED,
  138. // This entry is available for regular IO.
  139. STATE_READY,
  140. // IO is currently in flight, operations must wait for completion before
  141. // launching.
  142. STATE_IO_PENDING,
  143. // A failure occurred in the current or previous operation. All operations
  144. // after that must fail, until we receive a Close().
  145. STATE_FAILURE,
  146. };
  147. enum DoomState {
  148. // No attempt to doom the entry has been made.
  149. DOOM_NONE,
  150. // We have moved ourselves to |entries_pending_doom_| and have queued an
  151. // operation to actually update the disk, but haven't completed it yet.
  152. DOOM_QUEUED,
  153. // The disk has been updated. This corresponds to the state where we
  154. // are in neither |entries_pending_doom_| nor |active_entries_|.
  155. DOOM_COMPLETED,
  156. };
  157. ~SimpleEntryImpl() override;
  158. // Must be used to invoke a client-provided completion callback for an
  159. // operation initiated through the backend (e.g. create, open, doom) so that
  160. // clients don't get notified after they deleted the backend (which they would
  161. // not expect).
  162. void PostClientCallback(CompletionOnceCallback callback, int result);
  163. void PostClientCallback(EntryResultCallback callback, EntryResult result);
  164. // Clears entry state enough to prepare it for re-use. This will generally
  165. // put it back into STATE_UNINITIALIZED, except if the entry is doomed and
  166. // therefore disconnected from ownership of corresponding filename, in which
  167. // case it will be put into STATE_FAILURE.
  168. void ResetEntry();
  169. // Adjust ownership before return of this entry to a user of the API.
  170. // Increments the user count.
  171. void ReturnEntryToCaller();
  172. // Like above, but for asynchronous return after the event loop runs again,
  173. // also invoking the callback per the usual net convention.
  174. // The return is cancelled if the backend is deleted in the interim.
  175. void ReturnEntryToCallerAsync(bool is_open, EntryResultCallback callback);
  176. // Portion of the above that runs off the event loop.
  177. void FinishReturnEntryToCallerAsync(bool is_open,
  178. EntryResultCallback callback);
  179. // Remove |this| from the Backend and the index, either because
  180. // SimpleSynchronousEntry has detected an error or because we are about to
  181. // be dooming it ourselves and want it to be tracked in
  182. // |entries_pending_doom_| instead.
  183. void MarkAsDoomed(DoomState doom_state);
  184. // Runs the next operation in the queue, if any and if there is no other
  185. // operation running at the moment.
  186. // WARNING: May delete |this|, as an operation in the queue can contain
  187. // the last reference.
  188. void RunNextOperationIfNeeded();
  189. void OpenEntryInternal(SimpleEntryOperation::EntryResultState result_state,
  190. EntryResultCallback callback);
  191. void CreateEntryInternal(SimpleEntryOperation::EntryResultState result_state,
  192. EntryResultCallback callback);
  193. void OpenOrCreateEntryInternal(
  194. OpenEntryIndexEnum index_state,
  195. SimpleEntryOperation::EntryResultState result_state,
  196. EntryResultCallback callback);
  197. void CloseInternal();
  198. int ReadDataInternal(bool sync_possible,
  199. int index,
  200. int offset,
  201. net::IOBuffer* buf,
  202. int buf_len,
  203. CompletionOnceCallback callback);
  204. void WriteDataInternal(int index,
  205. int offset,
  206. net::IOBuffer* buf,
  207. int buf_len,
  208. CompletionOnceCallback callback,
  209. bool truncate);
  210. void ReadSparseDataInternal(int64_t sparse_offset,
  211. net::IOBuffer* buf,
  212. int buf_len,
  213. CompletionOnceCallback callback);
  214. void WriteSparseDataInternal(int64_t sparse_offset,
  215. net::IOBuffer* buf,
  216. int buf_len,
  217. CompletionOnceCallback callback);
  218. void GetAvailableRangeInternal(int64_t sparse_offset,
  219. int len,
  220. RangeResultCallback callback);
  221. void DoomEntryInternal(CompletionOnceCallback callback);
  222. // Called after a SimpleSynchronousEntry has completed CreateEntry() or
  223. // OpenEntry(). If |in_results| is used to denote whether that was successful,
  224. // Posts either the produced entry or an error code to |completion_callback|.
  225. void CreationOperationComplete(
  226. SimpleEntryOperation::EntryResultState result_state,
  227. EntryResultCallback completion_callback,
  228. const base::TimeTicks& start_time,
  229. const base::Time index_last_used_time,
  230. std::unique_ptr<SimpleEntryCreationResults> in_results,
  231. net::NetLogEventType end_event_type);
  232. // Called after we've closed and written the EOF record to our entry. Until
  233. // this point it hasn't been safe to OpenEntry() the same entry, but from this
  234. // point it is.
  235. void CloseOperationComplete(
  236. std::unique_ptr<SimpleEntryCloseResults> in_results);
  237. // Internal utility method used by other completion methods.
  238. // Updaties state and dooms on errors.
  239. void UpdateStateAfterOperationComplete(const SimpleEntryStat& entry_stat,
  240. int result);
  241. // Internal utility method used by other completion methods. Calls
  242. // |completion_callback| after updating state and dooming on errors.
  243. void EntryOperationComplete(CompletionOnceCallback completion_callback,
  244. const SimpleEntryStat& entry_stat,
  245. int result);
  246. // Called after an asynchronous read. Updates |crc32s_| if possible.
  247. void ReadOperationComplete(
  248. int stream_index,
  249. int offset,
  250. CompletionOnceCallback completion_callback,
  251. std::unique_ptr<SimpleEntryStat> entry_stat,
  252. std::unique_ptr<SimpleSynchronousEntry::ReadResult> read_result);
  253. // Called after an asynchronous write completes.
  254. // |buf| parameter brings back a reference to net::IOBuffer to the original
  255. // sequence, so that we can reduce cross thread malloc/free pair.
  256. // See http://crbug.com/708644 for details.
  257. void WriteOperationComplete(
  258. int stream_index,
  259. CompletionOnceCallback completion_callback,
  260. std::unique_ptr<SimpleEntryStat> entry_stat,
  261. std::unique_ptr<SimpleSynchronousEntry::WriteResult> result,
  262. net::IOBuffer* buf);
  263. void ReadSparseOperationComplete(CompletionOnceCallback completion_callback,
  264. std::unique_ptr<base::Time> last_used,
  265. std::unique_ptr<int> result);
  266. void WriteSparseOperationComplete(CompletionOnceCallback completion_callback,
  267. std::unique_ptr<SimpleEntryStat> entry_stat,
  268. std::unique_ptr<int> result);
  269. void GetAvailableRangeOperationComplete(
  270. RangeResultCallback completion_callback,
  271. std::unique_ptr<RangeResult> result);
  272. // Called after an asynchronous doom completes.
  273. void DoomOperationComplete(CompletionOnceCallback callback,
  274. State state_to_restore,
  275. int result);
  276. // Called after completion of an operation, to either incoproprate file info
  277. // received from I/O done on the worker pool, or to simply bump the
  278. // timestamps. Updates the metadata both in |this| and in the index.
  279. // Stream size information in particular may be important for following
  280. // operations.
  281. void UpdateDataFromEntryStat(const SimpleEntryStat& entry_stat);
  282. int64_t GetDiskUsage() const;
  283. // Completes a read from the stream data kept in memory, logging metrics
  284. // and updating metadata. Returns the # of bytes read successfully.
  285. // This asumes the caller has already range-checked offset and buf_len
  286. // appropriately.
  287. int ReadFromBuffer(net::GrowableIOBuffer* in_buf,
  288. int offset,
  289. int buf_len,
  290. net::IOBuffer* out_buf);
  291. // Copies data from |buf| to the internal in-memory buffer for stream 0. If
  292. // |truncate| is set to true, the target buffer will be truncated at |offset|
  293. // + |buf_len| before being written.
  294. int SetStream0Data(net::IOBuffer* buf,
  295. int offset, int buf_len,
  296. bool truncate);
  297. // We want all async I/O on entries to complete before recycling the dir.
  298. scoped_refptr<BackendCleanupTracker> cleanup_tracker_;
  299. std::unique_ptr<ActiveEntryProxy> active_entry_proxy_;
  300. // All nonstatic SimpleEntryImpl methods should always be called on the
  301. // source creation sequence, in all cases. |sequence_checker_| documents and
  302. // enforces this.
  303. SEQUENCE_CHECKER(sequence_checker_);
  304. const base::WeakPtr<SimpleBackendImpl> backend_;
  305. const raw_ptr<SimpleFileTracker> file_tracker_;
  306. const scoped_refptr<BackendFileOperationsFactory> file_operations_factory_;
  307. const net::CacheType cache_type_;
  308. const base::FilePath path_;
  309. const uint64_t entry_hash_;
  310. const bool use_optimistic_operations_;
  311. std::string key_;
  312. // |last_used_|, |last_modified_| and |data_size_| are copied from the
  313. // synchronous entry at the completion of each item of asynchronous IO.
  314. // TODO(clamy): Unify last_used_ with data in the index.
  315. base::Time last_used_;
  316. base::Time last_modified_;
  317. int32_t data_size_[kSimpleEntryStreamCount];
  318. int32_t sparse_data_size_ = 0;
  319. // Number of times this object has been returned from Backend::OpenEntry() and
  320. // Backend::CreateEntry() without subsequent Entry::Close() calls. Used to
  321. // notify the backend when this entry not used by any callers.
  322. int open_count_ = 0;
  323. DoomState doom_state_ = DOOM_NONE;
  324. enum {
  325. CREATE_NORMAL,
  326. CREATE_OPTIMISTIC_PENDING_DOOM,
  327. CREATE_OPTIMISTIC_PENDING_DOOM_FOLLOWED_BY_DOOM,
  328. } optimistic_create_pending_doom_state_ = CREATE_NORMAL;
  329. State state_ = STATE_UNINITIALIZED;
  330. // When possible, we compute a crc32, for the data in each entry as we read or
  331. // write. For each stream, |crc32s_[index]| is the crc32 of that stream from
  332. // [0 .. |crc32s_end_offset_|). If |crc32s_end_offset_[index] == 0| then the
  333. // value of |crc32s_[index]| is undefined.
  334. // Note at this can only be done in the current implementation in the case of
  335. // a single entry reader that reads serially through the entire file.
  336. // Extending this to multiple readers is possible, but isn't currently worth
  337. // it; see http://crbug.com/488076#c3 for details.
  338. int32_t crc32s_end_offset_[kSimpleEntryStreamCount];
  339. uint32_t crc32s_[kSimpleEntryStreamCount];
  340. // If |have_written_[index]| is true, we have written to the file that
  341. // contains stream |index|.
  342. bool have_written_[kSimpleEntryStreamCount];
  343. // The |synchronous_entry_| is the worker thread object that performs IO on
  344. // entries. It's owned by this SimpleEntryImpl whenever |executing_operation_|
  345. // is false (i.e. when an operation is not pending on the worker pool). When
  346. // an operation is being executed no one owns the synchronous entry. Therefore
  347. // SimpleEntryImpl should not be deleted while an operation is running as that
  348. // would leak the SimpleSynchronousEntry.
  349. raw_ptr<SimpleSynchronousEntry> synchronous_entry_ = nullptr;
  350. scoped_refptr<net::PrioritizedTaskRunner> prioritized_task_runner_;
  351. base::queue<SimpleEntryOperation> pending_operations_;
  352. net::NetLogWithSource net_log_;
  353. // Unlike other streams, stream 0 data is read from the disk when the entry is
  354. // opened, and then kept in memory. All read/write operations on stream 0
  355. // affect the |stream_0_data_| buffer. When the entry is closed,
  356. // |stream_0_data_| is written to the disk.
  357. // Stream 0 is kept in memory because it is stored in the same file as stream
  358. // 1 on disk, to reduce the number of file descriptors and save disk space.
  359. // This strategy allows stream 1 to change size easily. Since stream 0 is only
  360. // used to write HTTP headers, the memory consumption of keeping it in memory
  361. // is acceptable.
  362. scoped_refptr<net::GrowableIOBuffer> stream_0_data_;
  363. // Sometimes stream 1 data is prefetched when stream 0 is first read.
  364. // If a write to the stream occurs on the entry the prefetch buffer is
  365. // discarded. It may also be null if it wasn't prefetched in the first place.
  366. scoped_refptr<net::GrowableIOBuffer> stream_1_prefetch_data_;
  367. // This is used only while a doom is pending.
  368. scoped_refptr<SimplePostDoomWaiterTable> post_doom_waiting_;
  369. // Choosing uint32_t over uint64_t for space savings. Pages have in the
  370. // hundres to possibly thousands of resources. Wrapping every 4 billion
  371. // shouldn't cause inverted priorities very often.
  372. uint32_t entry_priority_ = 0;
  373. };
  374. } // namespace disk_cache
  375. #endif // NET_DISK_CACHE_SIMPLE_SIMPLE_ENTRY_IMPL_H_