diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-01 05:12:51 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-01 05:12:51 +0000 |
commit | ed539d1fb033038ba8b99437e9acf8455d070056 (patch) | |
tree | 88c81bbee6768dc95fd6bf2d8207bc5b6a56f573 /content | |
parent | 7e7ee14307744fe8d46fe3942209ff220329663e (diff) | |
download | chromium_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.cc | 65 | ||||
-rw-r--r-- | content/child/fileapi/webfilewriter_impl.cc | 109 | ||||
-rw-r--r-- | content/child/fileapi/webfilewriter_impl.h | 13 |
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 |