summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-01 05:12:51 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-01 05:12:51 +0000
commited539d1fb033038ba8b99437e9acf8455d070056 (patch)
tree88c81bbee6768dc95fd6bf2d8207bc5b6a56f573 /content
parent7e7ee14307744fe8d46fe3942209ff220329663e (diff)
downloadchromium_src-ed539d1fb033038ba8b99437e9acf8455d070056.zip
chromium_src-ed539d1fb033038ba8b99437e9acf8455d070056.tar.gz
chromium_src-ed539d1fb033038ba8b99437e9acf8455d070056.tar.bz2
Implement Worker-MainThread bridge for FileWriter in Chrome
This basically adds the same worker/mainThread bridge functionality for FileWriter in Chrome side. BUG=257349 TEST=no behavioral changes yet R=michaeln@chromium.org Review URL: https://codereview.chromium.org/21041003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@214957 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/child/fileapi/webfilesystem_impl.cc65
-rw-r--r--content/child/fileapi/webfilewriter_impl.cc109
-rw-r--r--content/child/fileapi/webfilewriter_impl.h13
3 files changed, 147 insertions, 40 deletions
diff --git a/content/child/fileapi/webfilesystem_impl.cc b/content/child/fileapi/webfilesystem_impl.cc
index e253a17..090bf7d 100644
--- a/content/child/fileapi/webfilesystem_impl.cc
+++ b/content/child/fileapi/webfilesystem_impl.cc
@@ -94,19 +94,6 @@ class CallbacksMap : public WorkerTaskRunner::Observer {
DISALLOW_COPY_AND_ASSIGN(CallbacksMap);
};
-void DidReadMetadataForCreateFileWriter(
- const GURL& path,
- WebKit::WebFileWriterClient* client,
- WebKit::WebFileSystemCallbacks* callbacks,
- const base::PlatformFileInfo& file_info) {
- if (file_info.is_directory || file_info.size < 0) {
- callbacks->didFail(WebKit::WebFileErrorInvalidState);
- return;
- }
- callbacks->didCreateFileWriter(new WebFileWriterImpl(path, client),
- file_info.size);
-}
-
void DidReceiveSnapshotFile(int request_id) {
if (ChildThread::current())
ChildThread::current()->Send(
@@ -195,6 +182,37 @@ void ReadDirectoryCallbackAdapater(
MakeTuple(file_system_entries, has_more));
}
+void CreateFileWriterCallbackAdapter(
+ int thread_id, int callbacks_id,
+ base::MessageLoopProxy* main_thread_loop,
+ const GURL& path,
+ WebKit::WebFileWriterClient* client,
+ const base::PlatformFileInfo& file_info) {
+ if (thread_id != CurrentWorkerId()) {
+ WorkerTaskRunner::Instance()->PostTask(
+ thread_id,
+ base::Bind(&CreateFileWriterCallbackAdapter,
+ thread_id, callbacks_id,
+ make_scoped_refptr(main_thread_loop),
+ path, client, file_info));
+ return;
+ }
+
+ if (!CallbacksMap::Get())
+ return;
+
+ WebFileSystemCallbacks* callbacks =
+ CallbacksMap::Get()->GetAndUnregisterCallbacks(callbacks_id);
+ DCHECK(callbacks);
+
+ if (file_info.is_directory || file_info.size < 0) {
+ callbacks->didFail(WebKit::WebFileErrorInvalidState);
+ return;
+ }
+ callbacks->didCreateFileWriter(
+ new WebFileWriterImpl(path, client, main_thread_loop), file_info.size);
+}
+
void CreateSnapshotFileCallbackAdapter(
int thread_id, int callbacks_id,
base::MessageLoopProxy* main_thread_loop,
@@ -368,22 +386,23 @@ void WebFileSystemImpl::readDirectory(
WebKit::WebFileWriter* WebFileSystemImpl::createFileWriter(
const WebURL& path, WebKit::WebFileWriterClient* client) {
- return new WebFileWriterImpl(GURL(path), client);
+ return new WebFileWriterImpl(GURL(path), client, main_thread_loop_.get());
}
void WebFileSystemImpl::createFileWriter(
const WebURL& path,
WebKit::WebFileWriterClient* client,
WebKit::WebFileSystemCallbacks* callbacks) {
- // TODO(kinuko): Convert this method to use bridge model. (crbug.com/257349)
- DCHECK(main_thread_loop_->RunsTasksOnCurrentThread());
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->ReadMetadata(
- GURL(path),
- base::Bind(&DidReadMetadataForCreateFileWriter,
- GURL(path), client, callbacks),
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+ int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::ReadMetadata,
+ MakeTuple(GURL(path),
+ base::Bind(&CreateFileWriterCallbackAdapter,
+ CurrentWorkerId(), callbacks_id, main_thread_loop_,
+ GURL(path), client),
+ base::Bind(&StatusCallbackAdapter,
+ CurrentWorkerId(), callbacks_id)));
}
void WebFileSystemImpl::createSnapshotFileAndReadMetadata(
diff --git a/content/child/fileapi/webfilewriter_impl.cc b/content/child/fileapi/webfilewriter_impl.cc
index 4cc72e3..881c57c 100644
--- a/content/child/fileapi/webfilewriter_impl.cc
+++ b/content/child/fileapi/webfilewriter_impl.cc
@@ -5,47 +5,128 @@
#include "content/child/fileapi/webfilewriter_impl.h"
#include "base/bind.h"
+#include "base/platform_file.h"
#include "content/child/child_thread.h"
#include "content/child/fileapi/file_system_dispatcher.h"
+#include "webkit/child/worker_task_runner.h"
+
+using webkit_glue::WorkerTaskRunner;
namespace content {
namespace {
-inline FileSystemDispatcher* GetFileSystemDispatcher() {
- return ChildThread::current()->file_system_dispatcher();
+FileSystemDispatcher* GetFileSystemDispatcher() {
+ return ChildThread::current() ?
+ ChildThread::current()->file_system_dispatcher() : NULL;
}
} // namespace
+typedef FileSystemDispatcher::StatusCallback StatusCallback;
+typedef FileSystemDispatcher::WriteCallback WriteCallback;
+
+// This instance may be created outside main thread but runs mainly
+// on main thread.
+class WebFileWriterImpl::WriterBridge
+ : public base::RefCountedThreadSafe<WriterBridge> {
+ public:
+ WriterBridge()
+ : request_id_(0),
+ thread_id_(WorkerTaskRunner::Instance()->CurrentWorkerId()) {}
+
+ void Truncate(const GURL& path, int64 offset,
+ const StatusCallback& status_callback) {
+ status_callback_ = status_callback;
+ if (!GetFileSystemDispatcher())
+ return;
+ ChildThread::current()->file_system_dispatcher()->Truncate(
+ path, offset, &request_id_,
+ base::Bind(&WriterBridge::DidFinish, this));
+ }
+
+ void Write(const GURL& path, const GURL& blob_url, int64 offset,
+ const WriteCallback& write_callback,
+ const StatusCallback& error_callback) {
+ write_callback_ = write_callback;
+ status_callback_ = error_callback;
+ if (!GetFileSystemDispatcher())
+ return;
+ ChildThread::current()->file_system_dispatcher()->Write(
+ path, blob_url, offset, &request_id_,
+ base::Bind(&WriterBridge::DidWrite, this),
+ base::Bind(&WriterBridge::DidFinish, this));
+ }
+
+ void Cancel(const StatusCallback& status_callback) {
+ status_callback_ = status_callback;
+ if (!GetFileSystemDispatcher())
+ return;
+ ChildThread::current()->file_system_dispatcher()->Cancel(
+ request_id_,
+ base::Bind(&WriterBridge::DidFinish, this));
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<WriterBridge>;
+ virtual ~WriterBridge() {}
+
+ void DidWrite(int64 bytes, bool complete) {
+ PostTaskToWorker(base::Bind(write_callback_, bytes, complete));
+ }
+
+ void DidFinish(base::PlatformFileError status) {
+ PostTaskToWorker(base::Bind(status_callback_, status));
+ }
+
+ void PostTaskToWorker(const base::Closure& closure) {
+ if (!thread_id_)
+ closure.Run();
+ else
+ WorkerTaskRunner::Instance()->PostTask(thread_id_, closure);
+ }
+
+ StatusCallback status_callback_;
+ WriteCallback write_callback_;
+ int request_id_;
+ int thread_id_;
+};
+
WebFileWriterImpl::WebFileWriterImpl(
- const GURL& path, WebKit::WebFileWriterClient* client)
+ const GURL& path, WebKit::WebFileWriterClient* client,
+ base::MessageLoopProxy* main_thread_loop)
: WebFileWriterBase(path, client),
- request_id_(0) {
+ main_thread_loop_(main_thread_loop),
+ bridge_(new WriterBridge) {
}
WebFileWriterImpl::~WebFileWriterImpl() {
}
void WebFileWriterImpl::DoTruncate(const GURL& path, int64 offset) {
- // The FileSystemDispatcher takes ownership of the CallbackDispatcher.
- GetFileSystemDispatcher()->Truncate(
- path, offset, &request_id_,
- base::Bind(&WebFileWriterImpl::DidFinish, AsWeakPtr()));
+ RunOnMainThread(base::Bind(&WriterBridge::Truncate, bridge_,
+ path, offset,
+ base::Bind(&WebFileWriterImpl::DidFinish, AsWeakPtr())));
}
void WebFileWriterImpl::DoWrite(
const GURL& path, const GURL& blob_url, int64 offset) {
- GetFileSystemDispatcher()->Write(
- path, blob_url, offset, &request_id_,
+ RunOnMainThread(base::Bind(&WriterBridge::Write, bridge_,
+ path, blob_url, offset,
base::Bind(&WebFileWriterImpl::DidWrite, AsWeakPtr()),
- base::Bind(&WebFileWriterImpl::DidFinish, AsWeakPtr()));
+ base::Bind(&WebFileWriterImpl::DidFinish, AsWeakPtr())));
}
void WebFileWriterImpl::DoCancel() {
- GetFileSystemDispatcher()->Cancel(
- request_id_,
- base::Bind(&WebFileWriterImpl::DidFinish, AsWeakPtr()));
+ RunOnMainThread(base::Bind(&WriterBridge::Cancel, bridge_,
+ base::Bind(&WebFileWriterImpl::DidFinish, AsWeakPtr())));
+}
+
+void WebFileWriterImpl::RunOnMainThread(const base::Closure& closure) {
+ if (main_thread_loop_->RunsTasksOnCurrentThread())
+ closure.Run();
+ else
+ main_thread_loop_->PostTask(FROM_HERE, closure);
}
} // namespace content
diff --git a/content/child/fileapi/webfilewriter_impl.h b/content/child/fileapi/webfilewriter_impl.h
index 718139d..a9e574e 100644
--- a/content/child/fileapi/webfilewriter_impl.h
+++ b/content/child/fileapi/webfilewriter_impl.h
@@ -7,6 +7,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "webkit/renderer/fileapi/webfilewriter_base.h"
namespace content {
@@ -15,7 +16,9 @@ namespace content {
class WebFileWriterImpl : public fileapi::WebFileWriterBase,
public base::SupportsWeakPtr<WebFileWriterImpl> {
public:
- WebFileWriterImpl(const GURL& path, WebKit::WebFileWriterClient* client);
+ WebFileWriterImpl(const GURL& path,
+ WebKit::WebFileWriterClient* client,
+ base::MessageLoopProxy* main_thread_loop);
virtual ~WebFileWriterImpl();
protected:
@@ -26,8 +29,12 @@ class WebFileWriterImpl : public fileapi::WebFileWriterBase,
virtual void DoCancel() OVERRIDE;
private:
- class CallbackDispatcher;
- int request_id_;
+ class WriterBridge;
+
+ void RunOnMainThread(const base::Closure& closure);
+
+ scoped_refptr<base::MessageLoopProxy> main_thread_loop_;
+ scoped_refptr<WriterBridge> bridge_;
};
} // namespace content