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

Unified Diff: content/child/fileapi/webfilesystem_impl.cc

Issue 19387002: Implement Worker-MainThread bridge for FileSystem API in Chrome (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase + nits fix Created 7 years, 5 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: content/child/fileapi/webfilesystem_impl.cc
diff --git a/content/child/fileapi/webfilesystem_impl.cc b/content/child/fileapi/webfilesystem_impl.cc
index 9bb8664f9bcd3debf0d755ec8811c0665079c2df..013715d72f31503b2d1bfdbf8f589536279b47e3 100644
--- a/content/child/fileapi/webfilesystem_impl.cc
+++ b/content/child/fileapi/webfilesystem_impl.cc
@@ -5,6 +5,8 @@
#include "content/child/fileapi/webfilesystem_impl.h"
#include "base/bind.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
#include "content/child/child_thread.h"
#include "content/child/fileapi/file_system_dispatcher.h"
#include "content/child/fileapi/webfilesystem_callback_adapters.h"
@@ -13,6 +15,8 @@
#include "third_party/WebKit/public/platform/WebFileInfo.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURL.h"
+#include "url/gurl.h"
+#include "webkit/child/worker_task_runner.h"
#include "webkit/glue/webkit_glue.h"
using WebKit::WebFileInfo;
@@ -21,6 +25,7 @@ using WebKit::WebFileSystemEntry;
using WebKit::WebString;
using WebKit::WebURL;
using WebKit::WebVector;
+using webkit_glue::WorkerTaskRunner;
namespace content {
@@ -39,107 +44,254 @@ void DidReadMetadataForCreateFileWriter(
file_info.size);
}
+int CurrentWorkerId() {
+ return WorkerTaskRunner::Instance()->CurrentWorkerId();
+}
+
+class CallbacksWrapper
+ : public WebFileSystemCallbacks,
+ public WorkerTaskRunner::Observer {
+ public:
+ explicit CallbacksWrapper(WebFileSystemCallbacks* original_callbacks)
+ : callbacks_(original_callbacks),
+ thread_id_(CurrentWorkerId()) {
+ if (thread_id_)
+ WorkerTaskRunner::Instance()->AddStopObserver(this);
+ }
+
+ virtual ~CallbacksWrapper() {
+ if (CurrentWorkerId())
+ WorkerTaskRunner::Instance()->RemoveStopObserver(this);
+ }
+
+ // WorkerTaskRunner::Observer overrides.
+ virtual void OnWorkerRunLoopStopped() OVERRIDE {
michaeln 2013/07/24 00:54:08 At this point the worker run loop is wound down an
michaeln 2013/07/24 01:38:58 Or i guess what i meant to say was, maybe just {
kinuko 2013/07/24 09:29:09 Current API is designed as 1. the callback is self
kinuko 2013/07/24 11:03:29 Well... on the second look the current API seems t
kinuko 2013/07/24 11:15:41 Oops, callbacks can't be deleted from outside sinc
+ callbacks_->didFail(WebKit::WebFileErrorAbort);
+ delete this;
michaeln 2013/07/24 06:19:13 Oh, I have another question about this method? Po
kinuko 2013/07/24 09:29:09 Ah, in the main thread side-- yes, good catch. Fi
+ }
+
+ // WebFileSystemCallbacks overrides.
+ virtual void didSucceed() OVERRIDE {
+ RunCallback(base::Bind(&WebFileSystemCallbacks::didSucceed,
+ base::Unretained(callbacks_)));
+ }
+ virtual void didReadMetadata(const WebFileInfo& info) OVERRIDE {
+ RunCallback(base::Bind(&WebFileSystemCallbacks::didReadMetadata,
+ base::Unretained(callbacks_), info));
+ }
+ virtual void didReadDirectory(const WebVector<WebFileSystemEntry>& entries,
+ bool hasMore) OVERRIDE {
+ RunCallback(base::Bind(&WebFileSystemCallbacks::didReadDirectory,
+ base::Unretained(callbacks_), entries, hasMore));
+ }
+ virtual void didOpenFileSystem(const WebString& name,
+ const WebURL& rootURL) OVERRIDE {
+ RunCallback(base::Bind(&WebFileSystemCallbacks::didOpenFileSystem,
+ base::Unretained(callbacks_), name, rootURL));
+ }
+ virtual void didFail(WebKit::WebFileError error) OVERRIDE {
+ RunCallback(base::Bind(&WebFileSystemCallbacks::didFail,
+ base::Unretained(callbacks_), error));
+ }
+ virtual bool shouldBlockUntilCompletion() const OVERRIDE {
+ return callbacks_->shouldBlockUntilCompletion();
+ }
+
+ void DidCreateSnapshotFile(const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path,
+ const base::Closure& did_receive_snapshot) {
+ if (thread_id_ != CurrentWorkerId()) {
+ WorkerTaskRunner::Instance()->PostTask(
+ thread_id_,
+ base::Bind(&CallbacksWrapper::DidCreateSnapshotFile,
+ base::Unretained(this), file_info, platform_path,
+ did_receive_snapshot));
+ return;
+ }
+ scoped_ptr<CallbacksWrapper> deleter(this);
+ WebFileInfo web_file_info;
+ webkit_glue::PlatformFileInfoToWebFileInfo(file_info, &web_file_info);
+ web_file_info.platformPath = platform_path.AsUTF16Unsafe();
+ callbacks_->didCreateSnapshotFile(web_file_info);
+ did_receive_snapshot.Run();
+ }
+
+ private:
+ void RunCallback(const base::Closure& callback) {
+ if (thread_id_ != CurrentWorkerId()) {
+ WorkerTaskRunner::Instance()->PostTask(
+ thread_id_,
+ base::Bind(&CallbacksWrapper::RunCallback,
+ base::Unretained(this), callback));
+ return;
+ }
+ scoped_ptr<CallbacksWrapper> deleter(this);
+ callback.Run();
+ }
+
+ WebFileSystemCallbacks* callbacks_;
+ int thread_id_;
+};
+
+template <typename Method, typename Params>
+void CallDispatcherOnMainThread(
+ base::MessageLoopProxy* loop,
+ Method method, const Params& params,
+ WebFileSystemCallbacks* callbacks) {
+ if (!loop->RunsTasksOnCurrentThread()) {
+ loop->PostTask(FROM_HERE,
+ base::Bind(&CallDispatcherOnMainThread<Method, Params>,
+ make_scoped_refptr(loop),
+ method, params, callbacks));
+ return;
+ }
+ if (!ChildThread::current() ||
+ !ChildThread::current()->file_system_dispatcher()) {
+ callbacks->didFail(WebKit::WebFileErrorAbort);
michaeln 2013/07/24 00:54:08 It looks like didFail() can be called on the main
kinuko 2013/07/24 09:29:09 Done.
+ return;
+ }
+ DispatchToMethod(ChildThread::current()->file_system_dispatcher(),
+ method, params);
+}
+
} // namespace
-WebFileSystemImpl::WebFileSystemImpl() {
+WebFileSystemImpl::WebFileSystemImpl(
+ base::MessageLoopProxy* main_thread_loop)
+ : main_thread_loop_(main_thread_loop) {
+ // TODO(kinuko): Support creating and accessing WebFileSystemImpl on
+ // non-main thread. (crbug.com/257349)
+ DCHECK(main_thread_loop_->RunsTasksOnCurrentThread());
}
-void WebFileSystemImpl::move(const WebURL& src_path,
- const WebURL& dest_path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->Move(GURL(src_path),
- GURL(dest_path),
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+WebFileSystemImpl::~WebFileSystemImpl() {
}
-void WebFileSystemImpl::copy(const WebURL& src_path,
- const WebURL& dest_path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->Copy(GURL(src_path),
- GURL(dest_path),
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+// WebFileSystem implementation.
+void WebFileSystemImpl::move(
+ const WebKit::WebURL& src_path,
+ const WebKit::WebURL& dest_path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::Move,
+ MakeTuple(GURL(src_path), GURL(dest_path),
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::remove(const WebURL& path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->Remove(
- GURL(path),
- false /* recursive */,
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::copy(
+ const WebKit::WebURL& src_path,
+ const WebKit::WebURL& dest_path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::Copy,
+ MakeTuple(GURL(src_path), GURL(dest_path),
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::removeRecursively(const WebURL& path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->Remove(
- GURL(path),
- true /* recursive */,
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::remove(
+ const WebKit::WebURL& path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::Remove,
+ MakeTuple(GURL(path), false /* recursive */,
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::readMetadata(const WebURL& path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->ReadMetadata(
- GURL(path),
- base::Bind(&ReadMetadataCallbackAdapter, callbacks),
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::removeRecursively(
+ const WebKit::WebURL& path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::Remove,
+ MakeTuple(GURL(path), true /* recursive */,
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::createFile(const WebURL& path,
- bool exclusive,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->CreateFile(
- GURL(path), exclusive,
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::readMetadata(
+ const WebKit::WebURL& path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::ReadMetadata,
+ MakeTuple(GURL(path),
+ base::Bind(&ReadMetadataCallbackAdapter, wrapper),
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::createDirectory(const WebURL& path,
- bool exclusive,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->CreateDirectory(
- GURL(path), exclusive, false /* recursive */,
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::createFile(
+ const WebKit::WebURL& path,
+ bool exclusive,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::CreateFile,
+ MakeTuple(GURL(path), exclusive,
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::fileExists(const WebURL& path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->Exists(
- GURL(path), false /* directory */,
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::createDirectory(
+ const WebKit::WebURL& path,
+ bool exclusive,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::CreateDirectory,
+ MakeTuple(GURL(path), exclusive, false /* recursive */,
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::directoryExists(const WebURL& path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->Exists(
- GURL(path), true /* directory */,
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::fileExists(
+ const WebKit::WebURL& path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::Exists,
+ MakeTuple(GURL(path), false /* directory */,
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
-void WebFileSystemImpl::readDirectory(const WebURL& path,
- WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->ReadDirectory(
- GURL(path),
- base::Bind(&ReadDirectoryCallbackAdapater, callbacks),
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+void WebFileSystemImpl::directoryExists(
+ const WebKit::WebURL& path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::Exists,
+ MakeTuple(GURL(path), true /* directory */,
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
+}
+
+void WebFileSystemImpl::readDirectory(
+ const WebKit::WebURL& path,
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::ReadDirectory,
+ MakeTuple(GURL(path),
+ base::Bind(&ReadDirectoryCallbackAdapater, wrapper),
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
WebKit::WebFileWriter* WebFileSystemImpl::createFileWriter(
@@ -151,6 +303,8 @@ 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(
@@ -163,12 +317,15 @@ void WebFileSystemImpl::createFileWriter(
void WebFileSystemImpl::createSnapshotFileAndReadMetadata(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
- FileSystemDispatcher* dispatcher =
- ChildThread::current()->file_system_dispatcher();
- dispatcher->CreateSnapshotFile(
- GURL(path),
- base::Bind(&CreateSnapshotFileCallbackAdapter, callbacks),
- base::Bind(&FileStatusCallbackAdapter, callbacks));
+ CallbacksWrapper* wrapper = new CallbacksWrapper(callbacks);
+ CallDispatcherOnMainThread(
+ main_thread_loop_.get(),
+ &FileSystemDispatcher::CreateSnapshotFile,
+ MakeTuple(GURL(path),
+ base::Bind(&CallbacksWrapper::DidCreateSnapshotFile,
+ base::Unretained(wrapper)),
+ base::Bind(&FileStatusCallbackAdapter, wrapper)),
+ wrapper);
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698