// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_ #define NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_ #include #include "base/message_loop_proxy.h" #include "net/base/completion_callback.h" #include "net/base/io_buffer.h" #include "net/disk_cache/entry_impl.h" #include "net/disk_cache/in_flight_io.h" namespace disk_cache { class BackendImpl; // This class represents a single asynchronous disk cache IO operation while it // is being bounced between threads. class BackendIO : public BackgroundIO { public: BackendIO(InFlightIO* controller, BackendImpl* backend, net::CompletionCallback* callback); // Runs the actual operation on the background thread. void ExecuteOperation(); // Callback implementation. void OnIOComplete(int result); // Returns true if this operation is directed to an entry (vs. the backend). bool IsEntryOperation(); net::CompletionCallback* callback() { return callback_; } void ReleaseEntry(); // The operations we proxy: void Init(); void OpenEntry(const std::string& key, Entry** entry); void CreateEntry(const std::string& key, Entry** entry); void DoomEntry(const std::string& key); void DoomAllEntries(); void DoomEntriesBetween(const base::Time initial_time, const base::Time end_time); void DoomEntriesSince(const base::Time initial_time); void OpenNextEntry(void** iter, Entry** next_entry); void OpenPrevEntry(void** iter, Entry** prev_entry); void EndEnumeration(void* iterator); void CloseEntryImpl(EntryImpl* entry); void DoomEntryImpl(EntryImpl* entry); void FlushQueue(); // Dummy operation. void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, int buf_len); void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, int buf_len, bool truncate); void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len); void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len); void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start); void CancelSparseIO(EntryImpl* entry); void ReadyForSparseIO(EntryImpl* entry); private: // There are two types of operations to proxy: regular backend operations are // queued so that we don't have more than one operation going on at the same // time (for instance opening an entry and creating the same entry). On the // other hand, operations targeted to a given entry can be long lived and // support multiple simultaneous users (multiple reads or writes to the same // entry), so they are not queued, just posted to the worker thread as they // come. enum Operation { OP_NONE = 0, OP_INIT, OP_OPEN, OP_CREATE, OP_DOOM, OP_DOOM_ALL, OP_DOOM_BETWEEN, OP_DOOM_SINCE, OP_OPEN_NEXT, OP_OPEN_PREV, OP_END_ENUMERATION, OP_CLOSE_ENTRY, OP_DOOM_ENTRY, OP_FLUSH_QUEUE, OP_MAX_BACKEND, OP_READ, OP_WRITE, OP_READ_SPARSE, OP_WRITE_SPARSE, OP_GET_RANGE, OP_CANCEL_IO, OP_IS_READY }; ~BackendIO() {} void ExecuteBackendOperation(); void ExecuteEntryOperation(); BackendImpl* backend_; net::CompletionCallback* callback_; Operation operation_; net::CompletionCallbackImpl my_callback_; // The arguments of all the operations we proxy: std::string key_; Entry** entry_ptr_; base::Time initial_time_; base::Time end_time_; void** iter_ptr_; void* iter_; EntryImpl* entry_; int index_; int offset_; scoped_refptr buf_; int buf_len_; bool truncate_; int64 offset64_; int64* start_; DISALLOW_COPY_AND_ASSIGN(BackendIO); }; // The specialized controller that keeps track of current operations. class InFlightBackendIO : public InFlightIO { public: InFlightBackendIO(BackendImpl* backend, base::MessageLoopProxy* background_thread) : backend_(backend), background_thread_(background_thread) {} ~InFlightBackendIO() {} // The operations we proxy: void Init(net::CompletionCallback* callback); void OpenEntry(const std::string& key, Entry** entry, net::CompletionCallback* callback); void CreateEntry(const std::string& key, Entry** entry, net::CompletionCallback* callback); void DoomEntry(const std::string& key, net::CompletionCallback* callback); void DoomAllEntries(net::CompletionCallback* callback); void DoomEntriesBetween(const base::Time initial_time, const base::Time end_time, net::CompletionCallback* callback); void DoomEntriesSince(const base::Time initial_time, net::CompletionCallback* callback); void OpenNextEntry(void** iter, Entry** next_entry, net::CompletionCallback* callback); void OpenPrevEntry(void** iter, Entry** prev_entry, net::CompletionCallback* callback); void EndEnumeration(void* iterator); void CloseEntryImpl(EntryImpl* entry); void DoomEntryImpl(EntryImpl* entry); void FlushQueue(net::CompletionCallback* callback); void ReadData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, int buf_len, net::CompletionCallback* callback); void WriteData(EntryImpl* entry, int index, int offset, net::IOBuffer* buf, int buf_len, bool truncate, net::CompletionCallback* callback); void ReadSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, net::CompletionCallback* callback); void WriteSparseData(EntryImpl* entry, int64 offset, net::IOBuffer* buf, int buf_len, net::CompletionCallback* callback); void GetAvailableRange(EntryImpl* entry, int64 offset, int len, int64* start, net::CompletionCallback* callback); void CancelSparseIO(EntryImpl* entry); void ReadyForSparseIO(EntryImpl* entry, net::CompletionCallback* callback); // Blocks until all operations are cancelled or completed. void WaitForPendingIO(); scoped_refptr background_thread() { return background_thread_; } // Returns true if the current thread is the background thread. bool BackgroundIsCurrentThread() { return background_thread_->BelongsToCurrentThread(); } protected: virtual void OnOperationComplete(BackgroundIO* operation, bool cancel); private: typedef std::list > OperationList; void QueueOperation(BackendIO* operation); void PostOperation(BackendIO* operation); BackendImpl* backend_; scoped_refptr background_thread_; OperationList pending_ops_; // The list of operations to be posted. DISALLOW_COPY_AND_ASSIGN(InFlightBackendIO); }; } // namespace disk_cache #endif // NET_DISK_CACHE_IN_FLIGHT_BACKEND_IO_H_