summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi/file_system_operation.cc
diff options
context:
space:
mode:
authorericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-07 23:24:38 +0000
committerericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-07 23:24:38 +0000
commitbd1523876a769c375e0a40b8cfe8c999f40e6e99 (patch)
tree2a2f91b4feee685386936f897f84a41d99d8e721 /webkit/fileapi/file_system_operation.cc
parente7dd6d8bb28270d49684714aa03f8162ab558bc6 (diff)
downloadchromium_src-bd1523876a769c375e0a40b8cfe8c999f40e6e99.zip
chromium_src-bd1523876a769c375e0a40b8cfe8c999f40e6e99.tar.gz
chromium_src-bd1523876a769c375e0a40b8cfe8c999f40e6e99.tar.bz2
Resubmit of http://codereview.chromium.org/3476002/show but without the crashing bug.
BUG=none TEST=none Review URL: http://codereview.chromium.org/3618016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61879 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi/file_system_operation.cc')
-rw-r--r--webkit/fileapi/file_system_operation.cc60
1 files changed, 51 insertions, 9 deletions
diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc
index 29336a8..29690b9 100644
--- a/webkit/fileapi/file_system_operation.cc
+++ b/webkit/fileapi/file_system_operation.cc
@@ -5,8 +5,9 @@
#include "webkit/fileapi/file_system_operation.h"
#include "base/time.h"
-#include "googleurl/src/gurl.h"
+#include "net/url_request/url_request_context.h"
#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/fileapi/file_writer_delegate.h"
namespace fileapi {
@@ -24,6 +25,8 @@ FileSystemOperation::FileSystemOperation(
}
FileSystemOperation::~FileSystemOperation() {
+ if (file_writer_delegate_.get())
+ base::FileUtilProxy::Close(proxy_, file_writer_delegate_->file(), NULL);
}
void FileSystemOperation::CreateFile(const FilePath& path,
@@ -130,6 +133,7 @@ void FileSystemOperation::Remove(const FilePath& path, bool recursive) {
}
void FileSystemOperation::Write(
+ scoped_refptr<URLRequestContext> url_request_context,
const FilePath& path,
const GURL& blob_url,
int64 offset) {
@@ -137,7 +141,28 @@ void FileSystemOperation::Write(
DCHECK(kOperationNone == pending_operation_);
pending_operation_ = kOperationWrite;
#endif
- NOTREACHED();
+ DCHECK(blob_url.is_valid());
+ file_writer_delegate_.reset(new FileWriterDelegate(this, offset));
+ blob_request_.reset(new URLRequest(blob_url, file_writer_delegate_.get()));
+ blob_request_->set_context(url_request_context);
+ base::FileUtilProxy::CreateOrOpen(
+ proxy_,
+ path,
+ base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE |
+ base::PLATFORM_FILE_ASYNC,
+ callback_factory_.NewCallback(
+ &FileSystemOperation::OnFileOpenedForWrite));
+}
+
+void FileSystemOperation::OnFileOpenedForWrite(
+ base::PlatformFileError rv,
+ base::PassPlatformFile file,
+ bool created) {
+ if (base::PLATFORM_FILE_OK != rv) {
+ dispatcher_->DidFail(rv);
+ return;
+ }
+ file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get());
}
void FileSystemOperation::Truncate(const FilePath& path, int64 length) {
@@ -166,15 +191,32 @@ void FileSystemOperation::TouchFile(const FilePath& path,
// We can only get here on a write or truncate that's not yet completed.
// We don't support cancelling any other operation at this time.
void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation) {
+ if (file_writer_delegate_.get()) {
#ifndef NDEBUG
- DCHECK(kOperationTruncate == pending_operation_);
- // FIXME(ericu): Cancelling for writes coming soon.
+ DCHECK(kOperationWrite == pending_operation_);
#endif
- // We're cancelling a truncate operation, but we can't actually stop it
- // since it's been proxied to another thread. We need to save the
- // cancel_operation so that when the truncate returns, it can see that it's
- // been cancelled, report it, and report that the cancel has succeeded.
- cancel_operation_ = cancel_operation;
+ // Writes are done without proxying through FileUtilProxy after the initial
+ // opening of the PlatformFile. All state changes are done on this thread,
+ // so we're guaranteed to be able to shut down atomically. We do need to
+ // check that the file has been opened [which means the blob_request_ has
+ // been created], so we know how much we need to do.
+ if (blob_request_.get())
+ // This halts any calls to file_writer_delegate_ from blob_request_.
+ blob_request_->Cancel();
+
+ // This deletes us, and by proxy deletes file_writer_delegate_ if any.
+ dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT);
+ cancel_operation->dispatcher_->DidSucceed();
+ } else {
+#ifndef NDEBUG
+ DCHECK(kOperationTruncate == pending_operation_);
+#endif
+ // We're cancelling a truncate operation, but we can't actually stop it
+ // since it's been proxied to another thread. We need to save the
+ // cancel_operation so that when the truncate returns, it can see that it's
+ // been cancelled, report it, and report that the cancel has succeeded.
+ cancel_operation_ = cancel_operation;
+ }
}
void FileSystemOperation::DidCreateFileExclusive(