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