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