15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/disk_cache/blockfile/file.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/threading/worker_pool.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/net_errors.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/disk_cache/blockfile/in_flight_io.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/disk_cache/disk_cache.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This class represents a single asynchronous IO operation while it is being 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// bounced between threads. 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FileBackgroundIO : public disk_cache::BackgroundIO { 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Other than the actual parameters for the IO operation (including the 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |callback| that must be notified at the end), we need the controller that 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is keeping track of all operations. When done, we notify the controller 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // (we do NOT invoke the callback), in the worker thead that completed the 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // operation. 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileBackgroundIO(disk_cache::File* file, const void* buf, size_t buf_len, 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t offset, disk_cache::FileIOCallback* callback, 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disk_cache::InFlightIO* controller) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : disk_cache::BackgroundIO(controller), callback_(callback), file_(file), 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buf_(buf), buf_len_(buf_len), offset_(offset) { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disk_cache::FileIOCallback* callback() { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return callback_; 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disk_cache::File* file() { 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return file_; 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Read and Write are the operations that can be performed asynchronously. 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The actual parameters for the operation are setup in the constructor of 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the object. Both methods should be called from a worker thread, by posting 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a task to the WorkerPool (they are RunnableMethods). When finished, 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // controller->OnIOComplete() is called. 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Read(); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Write(); 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~FileBackgroundIO() {} 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disk_cache::FileIOCallback* callback_; 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disk_cache::File* file_; 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const void* buf_; 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t buf_len_; 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t offset_; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileBackgroundIO); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The specialized controller that keeps track of current operations. 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FileInFlightIO : public disk_cache::InFlightIO { 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileInFlightIO() {} 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~FileInFlightIO() {} 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // These methods start an asynchronous operation. The arguments have the same 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // semantics of the File asynchronous operations, with the exception that the 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // operation never finishes synchronously. 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PostRead(disk_cache::File* file, void* buf, size_t buf_len, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t offset, disk_cache::FileIOCallback* callback); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PostWrite(disk_cache::File* file, const void* buf, size_t buf_len, 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t offset, disk_cache::FileIOCallback* callback); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Invokes the users' completion callback at the end of the IO operation. 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |cancel| is true if the actual task posted to the thread is still 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // queued (because we are inside WaitForPendingIO), and false if said task is 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the one performing the call. 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnOperationComplete(disk_cache::BackgroundIO* operation, 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool cancel) OVERRIDE; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileInFlightIO); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// --------------------------------------------------------------------------- 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Runs on a worker thread. 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FileBackgroundIO::Read() { 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (file_->Read(const_cast<void*>(buf_), buf_len_, offset_)) { 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result_ = static_cast<int>(buf_len_); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result_ = net::ERR_CACHE_READ_FAILURE; 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NotifyController(); 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Runs on a worker thread. 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FileBackgroundIO::Write() { 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool rv = file_->Write(buf_, buf_len_, offset_); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result_ = rv ? static_cast<int>(buf_len_) : net::ERR_CACHE_WRITE_FAILURE; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NotifyController(); 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// --------------------------------------------------------------------------- 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FileInFlightIO::PostRead(disk_cache::File *file, void* buf, size_t buf_len, 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t offset, disk_cache::FileIOCallback *callback) { 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<FileBackgroundIO> operation( 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new FileBackgroundIO(file, buf, buf_len, offset, callback, this)); 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file->AddRef(); // Balanced on OnOperationComplete() 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WorkerPool::PostTask(FROM_HERE, 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&FileBackgroundIO::Read, operation.get()), true); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOperationPosted(operation.get()); 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FileInFlightIO::PostWrite(disk_cache::File* file, const void* buf, 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t buf_len, size_t offset, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disk_cache::FileIOCallback* callback) { 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<FileBackgroundIO> operation( 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new FileBackgroundIO(file, buf, buf_len, offset, callback, this)); 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file->AddRef(); // Balanced on OnOperationComplete() 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::WorkerPool::PostTask(FROM_HERE, 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&FileBackgroundIO::Write, operation.get()), true); 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnOperationPosted(operation.get()); 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Runs on the IO thread. 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FileInFlightIO::OnOperationComplete(disk_cache::BackgroundIO* operation, 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool cancel) { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileBackgroundIO* op = static_cast<FileBackgroundIO*>(operation); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) disk_cache::FileIOCallback* callback = op->callback(); 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int bytes = operation->result(); 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Release the references acquired in PostRead / PostWrite. 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) op->file()->Release(); 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback->OnFileIOComplete(bytes); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A static object that will broker all async operations. 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FileInFlightIO* s_file_operations = NULL; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns the current FileInFlightIO. 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FileInFlightIO* GetFileInFlightIO() { 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!s_file_operations) { 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s_file_operations = new FileInFlightIO; 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return s_file_operations; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Deletes the current FileInFlightIO. 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DeleteFileInFlightIO() { 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(s_file_operations); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete s_file_operations; 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) s_file_operations = NULL; 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace disk_cache { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochFile::File(base::File file) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : init_(true), 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mixed_(true), 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base_file_(file.Pass()) { 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::Init(const base::FilePath& name) { 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (base_file_.IsValid()) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::FLAG_WRITE; 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base_file_.Initialize(name, flags); 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return base_file_.IsValid(); 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::IsValid() const { 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return base_file_.IsValid(); 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::Read(void* buffer, size_t buffer_len, size_t offset) { 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(base_file_.IsValid()); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (buffer_len > static_cast<size_t>(kint32max) || 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offset > static_cast<size_t>(kint32max)) { 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int ret = base_file_.Read(offset, static_cast<char*>(buffer), buffer_len); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (static_cast<size_t>(ret) == buffer_len); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::Write(const void* buffer, size_t buffer_len, size_t offset) { 201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(base_file_.IsValid()); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (buffer_len > static_cast<size_t>(kint32max) || 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offset > static_cast<size_t>(kint32max)) { 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int ret = base_file_.Write(offset, static_cast<const char*>(buffer), 208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch buffer_len); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (static_cast<size_t>(ret) == buffer_len); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// We have to increase the ref counter of the file before performing the IO to 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// prevent the completion to happen with an invalid handle (if the file is 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// closed while the IO is in flight). 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::Read(void* buffer, size_t buffer_len, size_t offset, 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileIOCallback* callback, bool* completed) { 217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(base_file_.IsValid()); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!callback) { 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (completed) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *completed = true; 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Read(buffer, buffer_len, offset); 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (buffer_len > ULONG_MAX || offset > ULONG_MAX) 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetFileInFlightIO()->PostRead(this, buffer, buffer_len, offset, callback); 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *completed = false; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::Write(const void* buffer, size_t buffer_len, size_t offset, 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileIOCallback* callback, bool* completed) { 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(base_file_.IsValid()); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!callback) { 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (completed) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *completed = true; 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Write(buffer, buffer_len, offset); 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AsyncWrite(buffer, buffer_len, offset, callback, completed); 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::SetLength(size_t length) { 246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(base_file_.IsValid()); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (length > kuint32max) 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return base_file_.SetLength(length); 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)size_t File::GetLength() { 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(base_file_.IsValid()); 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int64 len = base_file_.GetLength(); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (len > static_cast<int64>(kuint32max)) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return kuint32max; 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return static_cast<size_t>(len); 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Static. 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void File::WaitForPendingIO(int* num_pending_io) { 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We may be running unit tests so we should allow be able to reset the 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // message loop. 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetFileInFlightIO()->WaitForPendingIO(); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteFileInFlightIO(); 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Static. 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void File::DropPendingIO() { 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetFileInFlightIO()->DropPendingIO(); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteFileInFlightIO(); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)File::~File() { 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbase::PlatformFile File::platform_file() const { 281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return base_file_.GetPlatformFile(); 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset, 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileIOCallback* callback, bool* completed) { 286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(base_file_.IsValid()); 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (buffer_len > ULONG_MAX || offset > ULONG_MAX) 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetFileInFlightIO()->PostWrite(this, buffer, buffer_len, offset, callback); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (completed) 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *completed = false; 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace disk_cache 298