Commit 7047cee0 authored by kinuko@chromium.org's avatar kinuko@chromium.org

2nd try: Support synchronous mode in WebFileWriterImpl

BUG=257349
TEST=no behavioral change yet

Review URL: https://chromiumcodereview.appspot.com/22363002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215871 0039d316-1c4b-4281-b951-d872f2087c98
parent 98ec18cd
...@@ -252,8 +252,11 @@ void DidCreateFileWriter( ...@@ -252,8 +252,11 @@ void DidCreateFileWriter(
callbacks->didFail(WebKit::WebFileErrorInvalidState); callbacks->didFail(WebKit::WebFileErrorInvalidState);
return; return;
} }
WebFileWriterImpl::Type type = callbacks->shouldBlockUntilCompletion() ?
WebFileWriterImpl::TYPE_SYNC : WebFileWriterImpl::TYPE_ASYNC;
callbacks->didCreateFileWriter( callbacks->didCreateFileWriter(
new WebFileWriterImpl(path, client, main_thread_loop), file_info.size); new WebFileWriterImpl(path, client, type, main_thread_loop),
file_info.size);
} }
void CreateFileWriterCallbackAdapter( void CreateFileWriterCallbackAdapter(
...@@ -488,7 +491,9 @@ base::Unretained(waitable_results))), ...@@ -488,7 +491,9 @@ base::Unretained(waitable_results))),
WebKit::WebFileWriter* WebFileSystemImpl::createFileWriter( WebKit::WebFileWriter* WebFileSystemImpl::createFileWriter(
const WebURL& path, WebKit::WebFileWriterClient* client) { const WebURL& path, WebKit::WebFileWriterClient* client) {
return new WebFileWriterImpl(GURL(path), client, main_thread_loop_.get()); return new WebFileWriterImpl(GURL(path), client,
WebFileWriterImpl::TYPE_ASYNC,
main_thread_loop_.get());
} }
void WebFileSystemImpl::createFileWriter( void WebFileSystemImpl::createFileWriter(
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/platform_file.h" #include "base/platform_file.h"
#include "base/synchronization/waitable_event.h"
#include "content/child/child_thread.h" #include "content/child/child_thread.h"
#include "content/child/fileapi/file_system_dispatcher.h" #include "content/child/fileapi/file_system_dispatcher.h"
#include "webkit/child/worker_task_runner.h" #include "webkit/child/worker_task_runner.h"
...@@ -31,9 +32,13 @@ typedef FileSystemDispatcher::WriteCallback WriteCallback; ...@@ -31,9 +32,13 @@ typedef FileSystemDispatcher::WriteCallback WriteCallback;
class WebFileWriterImpl::WriterBridge class WebFileWriterImpl::WriterBridge
: public base::RefCountedThreadSafe<WriterBridge> { : public base::RefCountedThreadSafe<WriterBridge> {
public: public:
WriterBridge() WriterBridge(WebFileWriterImpl::Type type)
: request_id_(0), : request_id_(0),
thread_id_(WorkerTaskRunner::Instance()->CurrentWorkerId()) {} thread_id_(WorkerTaskRunner::Instance()->CurrentWorkerId()),
written_bytes_(0) {
if (type == WebFileWriterImpl::TYPE_SYNC)
waitable_event_.reset(new base::WaitableEvent(false, false));
}
void Truncate(const GURL& path, int64 offset, void Truncate(const GURL& path, int64 offset,
const StatusCallback& status_callback) { const StatusCallback& status_callback) {
...@@ -67,12 +72,25 @@ class WebFileWriterImpl::WriterBridge ...@@ -67,12 +72,25 @@ class WebFileWriterImpl::WriterBridge
base::Bind(&WriterBridge::DidFinish, this)); base::Bind(&WriterBridge::DidFinish, this));
} }
base::WaitableEvent* waitable_event() {
return waitable_event_.get();
}
void WaitAndRun() {
waitable_event_->Wait();
DCHECK(!results_closure_.is_null());
results_closure_.Run();
}
private: private:
friend class base::RefCountedThreadSafe<WriterBridge>; friend class base::RefCountedThreadSafe<WriterBridge>;
virtual ~WriterBridge() {} virtual ~WriterBridge() {}
void DidWrite(int64 bytes, bool complete) { void DidWrite(int64 bytes, bool complete) {
PostTaskToWorker(base::Bind(write_callback_, bytes, complete)); written_bytes_ += bytes;
if (waitable_event_ && !complete)
return;
PostTaskToWorker(base::Bind(write_callback_, written_bytes_, complete));
} }
void DidFinish(base::PlatformFileError status) { void DidFinish(base::PlatformFileError status) {
...@@ -80,24 +98,36 @@ class WebFileWriterImpl::WriterBridge ...@@ -80,24 +98,36 @@ class WebFileWriterImpl::WriterBridge
} }
void PostTaskToWorker(const base::Closure& closure) { void PostTaskToWorker(const base::Closure& closure) {
if (!thread_id_) written_bytes_ = 0;
if (!thread_id_) {
DCHECK(!waitable_event_);
closure.Run(); closure.Run();
else return;
WorkerTaskRunner::Instance()->PostTask(thread_id_, closure); }
if (waitable_event_) {
results_closure_ = closure;
waitable_event_->Signal();
return;
}
WorkerTaskRunner::Instance()->PostTask(thread_id_, closure);
} }
StatusCallback status_callback_; StatusCallback status_callback_;
WriteCallback write_callback_; WriteCallback write_callback_;
int request_id_; int request_id_;
int thread_id_; int thread_id_;
int written_bytes_;
scoped_ptr<base::WaitableEvent> waitable_event_;
base::Closure results_closure_;
}; };
WebFileWriterImpl::WebFileWriterImpl( WebFileWriterImpl::WebFileWriterImpl(
const GURL& path, WebKit::WebFileWriterClient* client, const GURL& path, WebKit::WebFileWriterClient* client,
Type type,
base::MessageLoopProxy* main_thread_loop) base::MessageLoopProxy* main_thread_loop)
: WebFileWriterBase(path, client), : WebFileWriterBase(path, client),
main_thread_loop_(main_thread_loop), main_thread_loop_(main_thread_loop),
bridge_(new WriterBridge) { bridge_(new WriterBridge(type)) {
} }
WebFileWriterImpl::~WebFileWriterImpl() { WebFileWriterImpl::~WebFileWriterImpl() {
...@@ -123,10 +153,14 @@ void WebFileWriterImpl::DoCancel() { ...@@ -123,10 +153,14 @@ void WebFileWriterImpl::DoCancel() {
} }
void WebFileWriterImpl::RunOnMainThread(const base::Closure& closure) { void WebFileWriterImpl::RunOnMainThread(const base::Closure& closure) {
if (main_thread_loop_->RunsTasksOnCurrentThread()) if (main_thread_loop_->RunsTasksOnCurrentThread()) {
DCHECK(!bridge_->waitable_event());
closure.Run(); closure.Run();
else return;
main_thread_loop_->PostTask(FROM_HERE, closure); }
main_thread_loop_->PostTask(FROM_HERE, closure);
if (bridge_->waitable_event())
bridge_->WaitAndRun();
} }
} // namespace content } // namespace content
...@@ -16,8 +16,14 @@ namespace content { ...@@ -16,8 +16,14 @@ namespace content {
class WebFileWriterImpl : public fileapi::WebFileWriterBase, class WebFileWriterImpl : public fileapi::WebFileWriterBase,
public base::SupportsWeakPtr<WebFileWriterImpl> { public base::SupportsWeakPtr<WebFileWriterImpl> {
public: public:
enum Type {
TYPE_SYNC,
TYPE_ASYNC,
};
WebFileWriterImpl(const GURL& path, WebFileWriterImpl(const GURL& path,
WebKit::WebFileWriterClient* client, WebKit::WebFileWriterClient* client,
Type type,
base::MessageLoopProxy* main_thread_loop); base::MessageLoopProxy* main_thread_loop);
virtual ~WebFileWriterImpl(); virtual ~WebFileWriterImpl();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment