Home | History | Annotate | Download | only in disk_cache
      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_IN_FLIGHT_BACKEND_IO_H_
      6 #define NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_
      7 
      8 #include <list>
      9 #include <string>
     10 
     11 #include "base/message_loop/message_loop_proxy.h"
     12 #include "base/time/time.h"
     13 #include "net/base/completion_callback.h"
     14 #include "net/base/io_buffer.h"
     15 #include "net/disk_cache/in_flight_io.h"
     16 
     17 namespace disk_cache {
     18 
     19 class BackendImpl;
     20 class Entry;
     21 class EntryImpl;
     22 
     23 // This class represents a single asynchronous disk cache IO operation while it
     24 // is being bounced between threads.
     25 class BackendIO : public BackgroundIO {
     26  public:
     27   BackendIO(InFlightIO* controller, BackendImpl* backend,
     28             const net::CompletionCallback& callback);
     29 
     30   // Runs the actual operation on the background thread.
     31   void ExecuteOperation();
     32 
     33   // Callback implementation.
     34   void OnIOComplete(int result);
     35 
     36   // Called when we are finishing this operation. If |cancel| is true, the user
     37   // callback will not be invoked.
     38   void OnDone(bool cancel);
     39 
     40   // Returns true if this operation is directed to an entry (vs. the backend).
     41   bool IsEntryOperation();
     42 
     43   net::CompletionCallback callback() const { return callback_; }
     44 
     45   // Grabs an extra reference of entry_.
     46   void ReferenceEntry();
     47 
     48   // The operations we proxy:
     49   void Init();
     50   void OpenEntry(const std::string& key, Entry** entry);
     51   void CreateEntry(const std::string& key, Entry** entry);
     52   void DoomEntry(const std::string& key);
     53   void DoomAllEntries();
     54   void DoomEntriesBetween(const base::Time initial_time,
     55                           const base::Time end_time);
     56   void DoomEntriesSince(const base::Time initial_time);
     57   void OpenNextEntry(void** iter, Entry** next_entry);
     58   void OpenPrevEntry(void** iter, Entry** prev_entry);
     59   void EndEnumeration(void* iterator);
     60   void OnExternalCacheHit(const std::string& key);
     61   void CloseEntryImpl(EntryImpl* entry);
     62   void DoomEntryImpl(EntryImpl* entry);
     63   void FlushQueue();  // Dummy operation.
     64   void RunTask(const base::Closure& task);
     65   void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
     66                 int buf_len);
     67   void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
     68                  int buf_len, bool truncate);
     69   void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
     70                       int buf_len);
     71   void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
     72                        int buf_len);
     73   void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start);
     74   void CancelSparseIO(EntryImpl* entry);
     75   void ReadyForSparseIO(EntryImpl* entry);
     76 
     77  private:
     78   // There are two types of operations to proxy: regular backend operations are
     79   // executed sequentially (queued by the message loop). On the other hand,
     80   // operations targeted to a given entry can be long lived and support multiple
     81   // simultaneous users (multiple reads or writes to the same entry), and they
     82   // are subject to throttling, so we keep an explicit queue.
     83   enum Operation {
     84     OP_NONE = 0,
     85     OP_INIT,
     86     OP_OPEN,
     87     OP_CREATE,
     88     OP_DOOM,
     89     OP_DOOM_ALL,
     90     OP_DOOM_BETWEEN,
     91     OP_DOOM_SINCE,
     92     OP_OPEN_NEXT,
     93     OP_OPEN_PREV,
     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   void** iter_ptr_;
    131   void* iter_;
    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(BackendImpl* backend,
    150                     base::MessageLoopProxy* background_thread);
    151   virtual ~InFlightBackendIO();
    152 
    153   // Proxied operations.
    154   void Init(const net::CompletionCallback& callback);
    155   void OpenEntry(const std::string& key, Entry** entry,
    156                  const net::CompletionCallback& callback);
    157   void CreateEntry(const std::string& key, Entry** entry,
    158                    const net::CompletionCallback& callback);
    159   void DoomEntry(const std::string& key,
    160                  const net::CompletionCallback& callback);
    161   void DoomAllEntries(const net::CompletionCallback& callback);
    162   void DoomEntriesBetween(const base::Time initial_time,
    163                           const base::Time end_time,
    164                           const net::CompletionCallback& callback);
    165   void DoomEntriesSince(const base::Time initial_time,
    166                         const net::CompletionCallback& callback);
    167   void OpenNextEntry(void** iter, Entry** next_entry,
    168                      const net::CompletionCallback& callback);
    169   void OpenPrevEntry(void** iter, Entry** prev_entry,
    170                      const net::CompletionCallback& callback);
    171   void EndEnumeration(void* iterator);
    172   void OnExternalCacheHit(const std::string& key);
    173   void CloseEntryImpl(EntryImpl* entry);
    174   void DoomEntryImpl(EntryImpl* entry);
    175   void FlushQueue(const net::CompletionCallback& callback);
    176   void RunTask(const base::Closure& task,
    177                const net::CompletionCallback& callback);
    178   void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
    179                 int buf_len, const net::CompletionCallback& callback);
    180   void WriteData(
    181       EntryImpl* entry, int index, int offset, net::IOBuffer* buf,
    182       int buf_len, bool truncate, const net::CompletionCallback& callback);
    183   void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
    184                       int buf_len, const net::CompletionCallback& callback);
    185   void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf,
    186                        int buf_len, const net::CompletionCallback& callback);
    187   void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start,
    188                          const net::CompletionCallback& callback);
    189   void CancelSparseIO(EntryImpl* entry);
    190   void ReadyForSparseIO(EntryImpl* entry,
    191                         const net::CompletionCallback& callback);
    192 
    193   // Blocks until all operations are cancelled or completed.
    194   void WaitForPendingIO();
    195 
    196   scoped_refptr<base::MessageLoopProxy> background_thread() {
    197     return background_thread_;
    198   }
    199 
    200   // Returns true if the current thread is the background thread.
    201   bool BackgroundIsCurrentThread() {
    202     return background_thread_->BelongsToCurrentThread();
    203   }
    204 
    205   base::WeakPtr<InFlightBackendIO> GetWeakPtr();
    206 
    207  protected:
    208   virtual void OnOperationComplete(BackgroundIO* operation,
    209                                    bool cancel) OVERRIDE;
    210 
    211  private:
    212   void PostOperation(BackendIO* operation);
    213 
    214   BackendImpl* backend_;
    215   scoped_refptr<base::MessageLoopProxy> background_thread_;
    216   base::WeakPtrFactory<InFlightBackendIO> ptr_factory_;
    217 
    218   DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO);
    219 };
    220 
    221 }  // namespace disk_cache
    222 
    223 #endif  // NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_
    224