Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(737)

Unified Diff: chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc

Issue 496953003: [fsp] Make the reading operation abortable. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed formatting. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
diff --git a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
index b15314a4ccec694c6f3b5a39965a491b41e2a2b3..84a1288c35c852b080517b41d4cea9cdd94aba83 100644
--- a/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
+++ b/chrome/browser/chromeos/file_system_provider/fileapi/file_stream_reader.cc
@@ -30,50 +30,48 @@ void Int64ToIntCompletionCallback(net::CompletionCallback callback,
callback.Run(static_cast<int>(result));
}
-// Opens a file for reading and calls the completion callback. Must be called
-// on UI thread.
-void OpenFileOnUIThread(
- const fileapi::FileSystemURL& url,
- const FileStreamReader::OpenFileCompletedCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+} // namespace
- util::FileSystemURLParser parser(url);
- if (!parser.Parse()) {
- callback.Run(base::WeakPtr<ProvidedFileSystemInterface>(),
- base::FilePath(),
- 0 /* file_handle */,
- base::File::FILE_ERROR_SECURITY);
- return;
+class FileStreamReader::OperationRunner
+ : public base::RefCountedThreadSafe<FileStreamReader::OperationRunner> {
+ public:
+ OperationRunner() : file_handle_(-1) {}
+
+ // Opens a file for reading and calls the completion callback. Must be called
+ // on UI thread.
+ void OpenFileOnUIThread(
+ const fileapi::FileSystemURL& url,
+ const fileapi::AsyncFileUtil::StatusCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ util::FileSystemURLParser parser(url);
+ if (!parser.Parse()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback, base::File::FILE_ERROR_SECURITY));
+ return;
+ }
+
+ file_system_ = parser.file_system()->GetWeakPtr();
+ file_path_ = parser.file_path();
+ abort_callback_ = parser.file_system()->OpenFile(
+ file_path_,
+ ProvidedFileSystemInterface::OPEN_FILE_MODE_READ,
+ base::Bind(
+ &OperationRunner::OnOpenFileCompletedOnUIThread, this, callback));
}
- parser.file_system()->OpenFile(
- parser.file_path(),
- ProvidedFileSystemInterface::OPEN_FILE_MODE_READ,
- base::Bind(
- callback, parser.file_system()->GetWeakPtr(), parser.file_path()));
-}
-
-// Forwards results of calling OpenFileOnUIThread back to the IO thread.
-void OnOpenFileCompletedOnUIThread(
- const FileStreamReader::OpenFileCompletedCallback& callback,
- base::WeakPtr<ProvidedFileSystemInterface> file_system,
- const base::FilePath& file_path,
- int file_handle,
- base::File::Error result) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(callback, file_system, file_path, file_handle, result));
-}
-
// Closes a file. Ignores result, since it is called from a constructor.
// Must be called on UI thread.
-void CloseFileOnUIThread(base::WeakPtr<ProvidedFileSystemInterface> file_system,
- int file_handle) {
+ void CloseFileOnUIThread() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
hirono 2014/08/22 05:43:47 The indent is wrong from here?
mtomasz 2014/08/22 06:09:50 Done.
- if (file_system.get())
- file_system->CloseFile(file_handle, base::Bind(&EmptyStatusCallback));
+ if (file_system_.get() && file_handle_ != -1) {
+ file_system_->CloseFile(file_handle_, base::Bind(&EmptyStatusCallback));
+ // Closing a file must not be aborted, since we could end up on files which
+ // are never closed.
+ abort_callback_ = ProvidedFileSystemInterface::AbortCallback();
+ }
}
// Requests reading contents of a file. In case of either success or a failure
@@ -81,8 +79,6 @@ void CloseFileOnUIThread(base::WeakPtr<ProvidedFileSystemInterface> file_system,
// to false. This function guarantees that it will succeed only if the file has
// not been changed while reading. Must be called on UI thread.
void ReadFileOnUIThread(
- base::WeakPtr<ProvidedFileSystemInterface> file_system,
- int file_handle,
scoped_refptr<net::IOBuffer> buffer,
int64 offset,
int length,
@@ -90,56 +86,123 @@ void ReadFileOnUIThread(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// If the file system got unmounted, then abort the reading operation.
- if (!file_system.get()) {
- callback.Run(0, false /* has_more */, base::File::FILE_ERROR_ABORT);
+ if (!file_system_.get()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(
+ callback, 0, false /* has_more */, base::File::FILE_ERROR_ABORT));
return;
}
- file_system->ReadFile(file_handle, buffer, offset, length, callback);
-}
-
-// Forward the completion callback to IO thread.
-void OnReadChunkReceivedOnUIThread(
- const ProvidedFileSystemInterface::ReadChunkReceivedCallback&
- chunk_received_callback,
- int chunk_length,
- bool has_more,
- base::File::Error result) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(chunk_received_callback, chunk_length, has_more, result));
+ abort_callback_ = file_system_->ReadFile(
+ file_handle_,
+ buffer,
+ offset,
+ length,
+ base::Bind(
+ &OperationRunner::OnReadFileCompletedOnUIThread, this, callback));
}
// Requests metadata of a file. In case of either succes or a failure,
// |callback is executed. Must be called on UI thread.
void GetMetadataOnUIThread(
- base::WeakPtr<ProvidedFileSystemInterface> file_system,
- const base::FilePath& file_path,
const ProvidedFileSystemInterface::GetMetadataCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// If the file system got unmounted, then abort the get length operation.
- if (!file_system.get()) {
- callback.Run(EntryMetadata(), base::File::FILE_ERROR_ABORT);
+ if (!file_system_.get()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback, EntryMetadata(), base::File::FILE_ERROR_ABORT));
return;
}
- file_system->GetMetadata(file_path, callback);
+ abort_callback_ = file_system_->GetMetadata(
+ file_path_,
+ base::Bind(
+ &OperationRunner::OnGetMetadataCompletedOnUIThread, this, callback));
}
-// Forward the completion callback to IO thread.
-void OnGetMetadataReceivedOnUIThread(
- const ProvidedFileSystemInterface::GetMetadataCallback& callback,
- const EntryMetadata& metadata,
+// Aborts the most recent operation (if exists), and calls the callback.
+void AbortOnUIThread(const fileapi::AsyncFileUtil::StatusCallback& callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (abort_callback_.is_null()) {
+ // No operation to be cancelled. At most a callback call, which will be
+ // discarded.
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(callback, base::File::FILE_OK));
+ return;
+ }
+
+ const ProvidedFileSystemInterface::AbortCallback abort_callback =
+ abort_callback_;
+ abort_callback_ = ProvidedFileSystemInterface::AbortCallback();
+ abort_callback.Run(
+ base::Bind(&OperationRunner::OnAbortCompletedOnUIThread, this, callback));
+}
+
+private:
+friend class base::RefCountedThreadSafe<OperationRunner>;
+
+virtual ~OperationRunner() {}
+
+// Remembers a file handle for further operations and forwards the result to
+// the IO thread.
+void OnOpenFileCompletedOnUIThread(
+ const fileapi::AsyncFileUtil::StatusCallback& callback,
+ int file_handle,
base::File::Error result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ file_handle_ = file_handle;
BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE, base::Bind(callback, metadata, result));
-}
+ BrowserThread::IO, FROM_HERE, base::Bind(callback, result));
+ }
-} // namespace
+ // Forwards a metadata to the IO thread.
+ void OnGetMetadataCompletedOnUIThread(
+ const ProvidedFileSystemInterface::GetMetadataCallback& callback,
+ const EntryMetadata& metadata,
+ base::File::Error result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE, base::Bind(callback, metadata, result));
+ }
+
+ // Forwards a response of reading from a file to the IO thread.
+ void OnReadFileCompletedOnUIThread(
+ const ProvidedFileSystemInterface::ReadChunkReceivedCallback&
+ chunk_received_callback,
+ int chunk_length,
+ bool has_more,
+ base::File::Error result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(chunk_received_callback, chunk_length, has_more, result));
+ }
+
+ // Forwards a response of aborting an operation to the IO thread.
+ void OnAbortCompletedOnUIThread(
+ const fileapi::AsyncFileUtil::StatusCallback& callback,
+ base::File::Error result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE, base::Bind(callback, result));
+ }
+
+ ProvidedFileSystemInterface::AbortCallback abort_callback_;
+ base::WeakPtr<ProvidedFileSystemInterface> file_system_;
+ base::FilePath file_path_;
+ int file_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(OperationRunner);
+};
FileStreamReader::FileStreamReader(fileapi::FileSystemContext* context,
const fileapi::FileSystemURL& url,
@@ -149,16 +212,24 @@ FileStreamReader::FileStreamReader(fileapi::FileSystemContext* context,
current_offset_(initial_offset),
current_length_(0),
expected_modification_time_(expected_modification_time),
+ runner_(new OperationRunner),
state_(NOT_INITIALIZED),
- file_handle_(0),
weak_ptr_factory_(this) {
}
FileStreamReader::~FileStreamReader() {
+ // FileStreamReader doesn't have a Cancel() method like in FileStreamWriter.
+ // Therefore, aborting is done from the destructor.
+ BrowserThread::PostTask(BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&OperationRunner::AbortOnUIThread,
+ runner_,
+ base::Bind(&EmptyStatusCallback)));
+
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
- base::Bind(&CloseFileOnUIThread, file_system_, file_handle_));
+ base::Bind(&OperationRunner::CloseFileOnUIThread, runner_));
}
void FileStreamReader::Initialize(
@@ -170,21 +241,18 @@ void FileStreamReader::Initialize(
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
- base::Bind(&OpenFileOnUIThread,
+ base::Bind(&OperationRunner::OpenFileOnUIThread,
+ runner_,
url_,
- base::Bind(&OnOpenFileCompletedOnUIThread,
- base::Bind(&FileStreamReader::OnOpenFileCompleted,
- weak_ptr_factory_.GetWeakPtr(),
- pending_closure,
- error_callback))));
+ base::Bind(&FileStreamReader::OnOpenFileCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ pending_closure,
+ error_callback)));
}
void FileStreamReader::OnOpenFileCompleted(
const base::Closure& pending_closure,
const net::Int64CompletionCallback& error_callback,
- base::WeakPtr<ProvidedFileSystemInterface> file_system,
- const base::FilePath& file_path,
- int file_handle,
base::File::Error result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_EQ(INITIALIZING, state_);
@@ -197,23 +265,18 @@ void FileStreamReader::OnOpenFileCompleted(
return;
}
- file_system_ = file_system;
- file_path_ = file_path;
- file_handle_ = file_handle;
- DCHECK_LT(0, file_handle);
+ DCHECK_EQ(base::File::FILE_OK, result);
// Verify the last modification time.
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
- base::Bind(&GetMetadataOnUIThread,
- file_system_,
- file_path_,
- base::Bind(&OnGetMetadataReceivedOnUIThread,
- base::Bind(&FileStreamReader::OnInitializeCompleted,
- weak_ptr_factory_.GetWeakPtr(),
- pending_closure,
- error_callback))));
+ base::Bind(&OperationRunner::GetMetadataOnUIThread,
+ runner_,
+ base::Bind(&FileStreamReader::OnInitializeCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ pending_closure,
+ error_callback)));
}
void FileStreamReader::OnInitializeCompleted(
@@ -341,16 +404,14 @@ void FileStreamReader::ReadAfterInitialized(
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
- base::Bind(&ReadFileOnUIThread,
- file_system_,
- file_handle_,
+ base::Bind(&OperationRunner::ReadFileOnUIThread,
+ runner_,
buffer,
current_offset_,
buffer_length,
- base::Bind(&OnReadChunkReceivedOnUIThread,
- base::Bind(&FileStreamReader::OnReadChunkReceived,
- weak_ptr_factory_.GetWeakPtr(),
- callback))));
+ base::Bind(&FileStreamReader::OnReadChunkReceived,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback)));
}
void FileStreamReader::GetLengthAfterInitialized(
@@ -362,14 +423,11 @@ void FileStreamReader::GetLengthAfterInitialized(
BrowserThread::UI,
FROM_HERE,
base::Bind(
- &GetMetadataOnUIThread,
- file_system_,
- file_path_,
- base::Bind(
- &OnGetMetadataReceivedOnUIThread,
- base::Bind(&FileStreamReader::OnGetMetadataForGetLengthReceived,
- weak_ptr_factory_.GetWeakPtr(),
- callback))));
+ &OperationRunner::GetMetadataOnUIThread,
+ runner_,
+ base::Bind(&FileStreamReader::OnGetMetadataForGetLengthReceived,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback)));
}
void FileStreamReader::OnReadChunkReceived(

Powered by Google App Engine
This is Rietveld 408576698