Home | History | Annotate | Download | only in blockfile
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
      6 #define NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
      7 
      8 #include <list>
      9 #include <string>
     10 
     11 #include "base/memory/ref_counted.h"
     12 #include "base/single_thread_task_runner.h"
     13 #include "base/time/time.h"
     14 #include "net/base/completion_callback.h"
     15 #include "net/base/io_buffer.h"
     16 #include "net/disk_cache/blockfile/in_flight_io.h"
     17 #include "net/disk_cache/blockfile/rankings.h"
     18 
     19 namespace disk_cache {
     20 
     21 class BackendImpl;
     22 class Entry;
     23 class EntryImpl;
     24 
     25 // This class represents a single asynchronous disk cache IO operation while it
     26 // is being bounced between threads.
     27 class BackendIO : public BackgroundIO {
     28  public:
     29   BackendIO(InFlightIO* controller, BackendImpl* backend,
     30             const net::CompletionCallback& callback);
     31 
     32   // Runs the actual operation on the background thread.
     33   void ExecuteOperation();
     34 
     35   // Callback implementation.
     36   void OnIOComplete(int result);
     37 
     38   // Called when we are finishing this operation. If |cancel| is true, the user
     39   // callback will not be invoked.
     40   void OnDone(bool cancel);
     41 
     42   // Returns true if this operation is directed to an entry (vs. the backend).
     43   bool IsEntryOperation();
     44 
     45   net::CompletionCallback callback() const { return callback_; }
     46 
     47   // Grabs an extra reference of entry_.
     48   void ReferenceEntry();
     49 
     50   // The operations we proxy:
     51   void Init();
     52   void OpenEntry(const std::string& key, Entry** entry);
     53   void CreateEntry(const std::string& key, Entry** entry);
     54   void DoomEntry(const std::string& key);
     55   void DoomAllEntries();
     56   void DoomEntriesBetween(const base::Time initial_time,
     57                           const base::Time end_time);
     58   void DoomEntriesSince(const base::Time initial_time);
     59   void OpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry);
     60   void EndEnumeration(scoped_ptr<Rankings::Iterator> iterator);
     61   void OnExternalCacheHit(const std::string& key);
     62   void CloseEntryImpl(EntryImpl* entry);
     63   void DoomEntryImpl(EntryImpl* entry);
     64   void FlushQueue();  // Dummy operation.
     65   void RunTask(const base::Closure& task);
     66   void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
     67                 int buf_len);
     68   void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
     69                  int buf_len, bool truncate);
     70   void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
     71                       int buf_len);
     72   void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
     73                        int buf_len);
     74   void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start);
     75   void CancelSparseIO(EntryImpl* entry);
     76   void ReadyForSparseIO(EntryImpl* entry);
     77 
     78  private:
     79   // There are two types of operations to proxy: regular backend operations are
     80   // executed sequentially (queued by the message loop). On the other hand,
     81   // operations targeted to a given entry can be long lived and support multiple
     82   // simultaneous users (multiple reads or writes to the same entry), and they
     83   // are subject to throttling, so we keep an explicit queue.
     84   enum Operation {
     85     OP_NONE = 0,
     86     OP_INIT,
     87     OP_OPEN,
     88     OP_CREATE,
     89     OP_DOOM,
     90     OP_DOOM_ALL,
     91     OP_DOOM_BETWEEN,
     92     OP_DOOM_SINCE,
     93     OP_OPEN_NEXT,
     94     OP_END_ENUMERATION,
     95     OP_ON_EXTERNAL_CACHE_HIT,
     96     OP_CLOSE_ENTRY,
     97     OP_DOOM_ENTRY,
     98     OP_FLUSH_QUEUE,
     99     OP_RUN_TASK,
    100     OP_MAX_BACKEND,
    101     OP_READ,
    102     OP_WRITE,
    103     OP_READ_SPARSE,
    104     OP_WRITE_SPARSE,
    105     OP_GET_RANGE,
    106     OP_CANCEL_IO,
    107     OP_IS_READY
    108   };
    109 
    110   virtual ~BackendIO();
    111 
    112   // Returns true if this operation returns an entry.
    113   bool ReturnsEntry();
    114 
    115   // Returns the time that has passed since the operation was created.
    116   base::TimeDelta ElapsedTime() const;
    117 
    118   void ExecuteBackendOperation();
    119   void ExecuteEntryOperation();
    120 
    121   BackendImpl* backend_;
    122   net::CompletionCallback callback_;
    123   Operation operation_;
    124 
    125   // The arguments of all the operations we proxy:
    126   std::string key_;
    127   Entry** entry_ptr_;
    128   base::Time initial_time_;
    129   base::Time end_time_;
    130   Rankings::Iterator* iterator_;
    131   scoped_ptr<Rankings::Iterator> scoped_iterator_;
    132   EntryImpl* entry_;
    133   int index_;
    134   int offset_;
    135   scoped_refptr<net::IOBuffer> buf_;
    136   int buf_len_;
    137   bool truncate_;
    138   int64 offset64_;
    139   int64* start_;
    140   base::TimeTicks start_time_;
    141   base::Closure task_;
    142 
    143   DISALLOW_COPY_AND_ASSIGN(BackendIO);
    144 };
    145 
    146 // The specialized controller that keeps track of current operations.
    147 class InFlightBackendIO : public InFlightIO {
    148  public:
    149   InFlightBackendIO(
    150       BackendImpl* backend,
    151       const scoped_refptr<base::SingleThreadTaskRunner>& background_thread);
    152   virtual ~InFlightBackendIO();
    153 
    154   // Proxied operations.
    155   void Init(const net::CompletionCallback& callback);
    156   void OpenEntry(const std::string& key, Entry** entry,
    157                  const net::CompletionCallback& callback);
    158   void CreateEntry(const std::string& key, Entry** entry,
    159                    const net::CompletionCallback& callback);
    160   void DoomEntry(const std::string& key,
    161                  const net::CompletionCallback& callback);
    162   void DoomAllEntries(const net::CompletionCallback& callback);
    163   void DoomEntriesBetween(const base::Time initial_time,
    164                           const base::Time end_time,
    165                           const net::CompletionCallback& callback);
    166   void DoomEntriesSince(const base::Time initial_time,
    167                         const net::CompletionCallback& callback);
    168   void OpenNextEntry(Rankings::Iterator* iterator, Entry** next_entry,
    169                      const net::CompletionCallback& callback);
    170   void EndEnumeration(scoped_ptr<Rankings::Iterator> iterator);
    171   void OnExternalCacheHit(const std::string& key);
    172   void CloseEntryImpl(EntryImpl* entry);
    173   void DoomEntryImpl(EntryImpl* entry);
    174   void FlushQueue(const net::CompletionCallback& callback);
    175   void RunTask(const base::Closure& task,
    176                const net::CompletionCallback& callback);
    177   void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
    178                 int buf_len, const net::CompletionCallback& callback);
    179   void WriteData(
    180       EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
    181       int buf_len, bool truncate, const net::CompletionCallback& callback);
    182   void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
    183                       int buf_len, const net::CompletionCallback& callback);
    184   void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
    185                        int buf_len, const net::CompletionCallback& callback);
    186   void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start,
    187                          const net::CompletionCallback& callback);
    188   void CancelSparseIO(EntryImpl* entry);
    189   void ReadyForSparseIO(EntryImpl* entry,
    190                         const net::CompletionCallback& callback);
    191 
    192   // Blocks until all operations are cancelled or completed.
    193   void WaitForPendingIO();
    194 
    195   scoped_refptr<base::SingleThreadTaskRunner> background_thread() {
    196     return background_thread_;
    197   }
    198 
    199   // Returns true if the current thread is the background thread.
    200   bool BackgroundIsCurrentThread() {
    201     return background_thread_->RunsTasksOnCurrentThread();
    202   }
    203 
    204   base::WeakPtr<InFlightBackendIO> GetWeakPtr();
    205 
    206  protected:
    207   virtual void OnOperationComplete(BackgroundIO* operation,
    208                                    bool cancel) OVERRIDE;
    209 
    210  private:
    211   void PostOperation(BackendIO* operation);
    212 
    213   BackendImpl* backend_;
    214   scoped_refptr<base::SingleThreadTaskRunner> background_thread_;
    215   base::WeakPtrFactory<InFlightBackendIO> ptr_factory_;
    216 
    217   DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO);
    218 };
    219 
    220 }  // namespace disk_cache
    221 
    222 #endif  // NET_DISK_CACHE_BLOCKFILE_IN_FLIGHT_BACKEND_IO_H_
    223