Index: webkit/browser/fileapi/file_system_operation_runner.cc |
diff --git a/webkit/browser/fileapi/file_system_operation_runner.cc b/webkit/browser/fileapi/file_system_operation_runner.cc |
index b899e1b598058191f6af1942e7aaf4ac732727b6..33eede7b2cd910a9ecc9c8af9b03f1188e3c89aa 100644 |
--- a/webkit/browser/fileapi/file_system_operation_runner.cc |
+++ b/webkit/browser/fileapi/file_system_operation_runner.cc |
@@ -5,6 +5,8 @@ |
#include "webkit/browser/fileapi/file_system_operation_runner.h" |
#include "base/bind.h" |
+#include "base/message_loop/message_loop_proxy.h" |
+#include "base/stl_util.h" |
#include "net/url_request/url_request_context.h" |
#include "webkit/browser/fileapi/file_observers.h" |
#include "webkit/browser/fileapi/file_stream_writer.h" |
@@ -17,7 +19,17 @@ namespace fileapi { |
typedef FileSystemOperationRunner::OperationID OperationID; |
-const OperationID FileSystemOperationRunner::kErrorOperationID = -1; |
+class FileSystemOperationRunner::BeginOperationScoper |
+ : public base::SupportsWeakPtr< |
+ FileSystemOperationRunner::BeginOperationScoper> { |
+ public: |
+ BeginOperationScoper() {} |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper); |
+}; |
+ |
+FileSystemOperationRunner::OperationHandle::OperationHandle() {} |
+FileSystemOperationRunner::OperationHandle::~OperationHandle() {} |
FileSystemOperationRunner::~FileSystemOperationRunner() { |
} |
@@ -33,17 +45,19 @@ OperationID FileSystemOperationRunner::CreateFile( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, url); |
+ PrepareForWrite(handle.id, url); |
operation->CreateFile( |
url, exclusive, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::CreateDirectory( |
@@ -54,17 +68,18 @@ OperationID FileSystemOperationRunner::CreateDirectory( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, url); |
+ PrepareForWrite(handle.id, url); |
operation->CreateDirectory( |
url, exclusive, recursive, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::Copy( |
@@ -74,18 +89,19 @@ OperationID FileSystemOperationRunner::Copy( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(dest_url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, dest_url); |
- PrepareForRead(id, src_url); |
+ PrepareForWrite(handle.id, dest_url); |
+ PrepareForRead(handle.id, src_url); |
operation->Copy( |
src_url, dest_url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::Move( |
@@ -95,18 +111,19 @@ OperationID FileSystemOperationRunner::Move( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(dest_url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, dest_url); |
- PrepareForWrite(id, src_url); |
+ PrepareForWrite(handle.id, dest_url); |
+ PrepareForWrite(handle.id, src_url); |
operation->Move( |
src_url, dest_url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::DirectoryExists( |
@@ -115,17 +132,18 @@ OperationID FileSystemOperationRunner::DirectoryExists( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForRead(id, url); |
+ PrepareForRead(handle.id, url); |
operation->DirectoryExists( |
url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::FileExists( |
@@ -134,17 +152,18 @@ OperationID FileSystemOperationRunner::FileExists( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForRead(id, url); |
+ PrepareForRead(handle.id, url); |
operation->FileExists( |
url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::GetMetadata( |
@@ -153,17 +172,18 @@ OperationID FileSystemOperationRunner::GetMetadata( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error, base::PlatformFileInfo()); |
- return kErrorOperationID; |
+ DidGetMetadata(handle, callback, error, base::PlatformFileInfo()); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForRead(id, url); |
+ PrepareForRead(handle.id, url); |
operation->GetMetadata( |
url, |
base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::ReadDirectory( |
@@ -172,17 +192,19 @@ OperationID FileSystemOperationRunner::ReadDirectory( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error, std::vector<DirectoryEntry>(), false); |
- return kErrorOperationID; |
+ DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(), |
+ false); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForRead(id, url); |
+ PrepareForRead(handle.id, url); |
operation->ReadDirectory( |
url, |
base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::Remove( |
@@ -191,17 +213,18 @@ OperationID FileSystemOperationRunner::Remove( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, url); |
+ PrepareForWrite(handle.id, url); |
operation->Remove( |
url, recursive, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::Write( |
@@ -213,17 +236,20 @@ OperationID FileSystemOperationRunner::Write( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error, 0, true); |
- return kErrorOperationID; |
+ DidWrite(handle, callback, error, 0, true); |
+ return handle.id; |
} |
scoped_ptr<FileStreamWriter> writer( |
file_system_context_->CreateFileStreamWriter(url, offset)); |
if (!writer) { |
// Write is not supported. |
- callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, 0, true); |
- return kErrorOperationID; |
+ DidWrite(handle, callback, base::PLATFORM_FILE_ERROR_SECURITY, 0, true); |
+ return handle.id; |
} |
DCHECK(blob_url.is_valid()); |
@@ -232,13 +258,12 @@ OperationID FileSystemOperationRunner::Write( |
scoped_ptr<net::URLRequest> blob_request(url_request_context->CreateRequest( |
blob_url, writer_delegate.get())); |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, url); |
+ PrepareForWrite(handle.id, url); |
operation->Write( |
url, writer_delegate.Pass(), blob_request.Pass(), |
base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::Truncate( |
@@ -247,28 +272,30 @@ OperationID FileSystemOperationRunner::Truncate( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, url); |
+ PrepareForWrite(handle.id, url); |
operation->Truncate( |
url, length, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
void FileSystemOperationRunner::Cancel( |
OperationID id, |
const StatusCallback& callback) { |
- FileSystemOperation* operation = operations_.Lookup(id); |
- if (!operation) { |
- // The operation is already finished; report that we failed to stop it. |
- callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
+ if (ContainsKey(finished_operations_, id)) { |
+ DCHECK(!ContainsKey(stray_cancel_callbacks_, id)); |
+ stray_cancel_callbacks_[id] = callback; |
return; |
} |
+ FileSystemOperation* operation = operations_.Lookup(id); |
+ DCHECK(operation); |
operation->Cancel(callback); |
} |
@@ -280,17 +307,18 @@ OperationID FileSystemOperationRunner::TouchFile( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForWrite(id, url); |
+ PrepareForWrite(handle.id, url); |
operation->TouchFile( |
url, last_access_time, last_modified_time, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::OpenFile( |
@@ -301,27 +329,28 @@ OperationID FileSystemOperationRunner::OpenFile( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error, base::kInvalidPlatformFileValue, |
- base::Closure(), base::ProcessHandle()); |
- return kErrorOperationID; |
+ DidOpenFile(handle, callback, error, base::kInvalidPlatformFileValue, |
+ base::Closure(), base::ProcessHandle()); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
if (file_flags & |
(base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_OPEN_ALWAYS | |
base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_TRUNCATED | |
base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE | |
base::PLATFORM_FILE_DELETE_ON_CLOSE | |
base::PLATFORM_FILE_WRITE_ATTRIBUTES)) { |
- PrepareForWrite(id, url); |
+ PrepareForWrite(handle.id, url); |
} else { |
- PrepareForRead(id, url); |
+ PrepareForRead(handle.id, url); |
} |
operation->OpenFile( |
url, file_flags, peer_handle, |
base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::CreateSnapshotFile( |
@@ -330,17 +359,19 @@ OperationID FileSystemOperationRunner::CreateSnapshotFile( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error, base::PlatformFileInfo(), base::FilePath(), NULL); |
- return kErrorOperationID; |
+ DidCreateSnapshot(handle, callback, error, base::PlatformFileInfo(), |
+ base::FilePath(), NULL); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
- PrepareForRead(id, url); |
+ PrepareForRead(handle.id, url); |
operation->CreateSnapshotFile( |
url, |
base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::CopyInForeignFile( |
@@ -350,16 +381,17 @@ OperationID FileSystemOperationRunner::CopyInForeignFile( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(dest_url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
operation->CopyInForeignFile( |
src_local_disk_path, dest_url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::RemoveFile( |
@@ -368,16 +400,17 @@ OperationID FileSystemOperationRunner::RemoveFile( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
operation->RemoveFile( |
url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::RemoveDirectory( |
@@ -386,16 +419,17 @@ OperationID FileSystemOperationRunner::RemoveDirectory( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
operation->RemoveDirectory( |
url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::CopyFileLocal( |
@@ -405,16 +439,17 @@ OperationID FileSystemOperationRunner::CopyFileLocal( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(src_url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
operation->CopyFileLocal( |
src_url, dest_url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
OperationID FileSystemOperationRunner::MoveFileLocal( |
@@ -424,16 +459,17 @@ OperationID FileSystemOperationRunner::MoveFileLocal( |
base::PlatformFileError error = base::PLATFORM_FILE_OK; |
FileSystemOperation* operation = |
file_system_context_->CreateFileSystemOperation(src_url, &error); |
+ BeginOperationScoper scope; |
+ OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
if (!operation) { |
- callback.Run(error); |
- return kErrorOperationID; |
+ DidFinish(handle, callback, error); |
+ return handle.id; |
} |
- OperationID id = operations_.Add(operation); |
operation->MoveFileLocal( |
src_url, dest_url, |
base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
- id, callback)); |
- return id; |
+ handle, callback)); |
+ return handle.id; |
} |
base::PlatformFileError FileSystemOperationRunner::SyncGetPlatformPath( |
@@ -452,64 +488,109 @@ FileSystemOperationRunner::FileSystemOperationRunner( |
: file_system_context_(file_system_context) {} |
void FileSystemOperationRunner::DidFinish( |
- OperationID id, |
+ OperationHandle handle, |
const StatusCallback& callback, |
base::PlatformFileError rv) { |
+ if (handle.scope) { |
+ finished_operations_.insert(handle.id); |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, base::Bind(&FileSystemOperationRunner::DidFinish, |
+ AsWeakPtr(), handle, callback, rv)); |
+ return; |
+ } |
callback.Run(rv); |
- FinishOperation(id); |
+ FinishOperation(handle.id); |
} |
void FileSystemOperationRunner::DidGetMetadata( |
- OperationID id, |
+ OperationHandle handle, |
const GetMetadataCallback& callback, |
base::PlatformFileError rv, |
const base::PlatformFileInfo& file_info) { |
+ if (handle.scope) { |
+ finished_operations_.insert(handle.id); |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, base::Bind(&FileSystemOperationRunner::DidGetMetadata, |
+ AsWeakPtr(), handle, callback, rv, file_info)); |
+ return; |
+ } |
callback.Run(rv, file_info); |
- FinishOperation(id); |
+ FinishOperation(handle.id); |
} |
void FileSystemOperationRunner::DidReadDirectory( |
- OperationID id, |
+ OperationHandle handle, |
const ReadDirectoryCallback& callback, |
base::PlatformFileError rv, |
const std::vector<DirectoryEntry>& entries, |
bool has_more) { |
+ if (handle.scope) { |
+ finished_operations_.insert(handle.id); |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory, |
+ AsWeakPtr(), handle, callback, rv, |
+ entries, has_more)); |
+ return; |
+ } |
callback.Run(rv, entries, has_more); |
if (rv != base::PLATFORM_FILE_OK || !has_more) |
- FinishOperation(id); |
+ FinishOperation(handle.id); |
} |
void FileSystemOperationRunner::DidWrite( |
- OperationID id, |
+ OperationHandle handle, |
const WriteCallback& callback, |
base::PlatformFileError rv, |
int64 bytes, |
bool complete) { |
+ if (handle.scope) { |
+ finished_operations_.insert(handle.id); |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), |
+ handle, callback, rv, bytes, complete)); |
+ return; |
+ } |
callback.Run(rv, bytes, complete); |
if (rv != base::PLATFORM_FILE_OK || complete) |
- FinishOperation(id); |
+ FinishOperation(handle.id); |
} |
void FileSystemOperationRunner::DidOpenFile( |
- OperationID id, |
+ OperationHandle handle, |
const OpenFileCallback& callback, |
base::PlatformFileError rv, |
base::PlatformFile file, |
const base::Closure& on_close_callback, |
base::ProcessHandle peer_handle) { |
+ if (handle.scope) { |
+ finished_operations_.insert(handle.id); |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, base::Bind(&FileSystemOperationRunner::DidOpenFile, |
+ AsWeakPtr(), handle, callback, rv, file, |
+ on_close_callback, peer_handle)); |
+ return; |
+ } |
callback.Run(rv, file, on_close_callback, peer_handle); |
- FinishOperation(id); |
+ FinishOperation(handle.id); |
} |
void FileSystemOperationRunner::DidCreateSnapshot( |
- OperationID id, |
+ OperationHandle handle, |
const SnapshotFileCallback& callback, |
base::PlatformFileError rv, |
const base::PlatformFileInfo& file_info, |
const base::FilePath& platform_path, |
const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { |
+ if (handle.scope) { |
+ finished_operations_.insert(handle.id); |
+ base::MessageLoopProxy::current()->PostTask( |
+ FROM_HERE, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, |
+ AsWeakPtr(), handle, callback, rv, file_info, |
+ platform_path, file_ref)); |
+ return; |
+ } |
callback.Run(rv, file_info, platform_path, file_ref); |
- FinishOperation(id); |
+ FinishOperation(handle.id); |
} |
void FileSystemOperationRunner::PrepareForWrite(OperationID id, |
@@ -529,6 +610,16 @@ void FileSystemOperationRunner::PrepareForRead(OperationID id, |
} |
} |
+FileSystemOperationRunner::OperationHandle |
+FileSystemOperationRunner::BeginOperation( |
+ FileSystemOperation* operation, |
+ base::WeakPtr<BeginOperationScoper> scope) { |
+ OperationHandle handle; |
+ handle.id = operations_.Add(operation); |
+ handle.scope = scope; |
+ return handle; |
+} |
+ |
void FileSystemOperationRunner::FinishOperation(OperationID id) { |
OperationToURLSet::iterator found = write_target_urls_.find(id); |
if (found != write_target_urls_.end()) { |
@@ -544,6 +635,17 @@ void FileSystemOperationRunner::FinishOperation(OperationID id) { |
} |
DCHECK(operations_.Lookup(id)); |
operations_.Remove(id); |
+ finished_operations_.erase(id); |
+ |
+ // Dispatch stray cancel callback if exists. |
+ std::map<OperationID, StatusCallback>::iterator found_cancel = |
+ stray_cancel_callbacks_.find(id); |
+ if (found_cancel != stray_cancel_callbacks_.end()) { |
+ // This cancel has been requested after the operation has finished, |
+ // so report that we failed to stop it. |
+ found_cancel->second.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
+ stray_cancel_callbacks_.erase(found_cancel); |
+ } |
} |
} // namespace fileapi |