summaryrefslogtreecommitdiffstats
path: root/content/child/fileapi
diff options
context:
space:
mode:
Diffstat (limited to 'content/child/fileapi')
-rw-r--r--content/child/fileapi/webfilesystem_impl.cc230
1 files changed, 171 insertions, 59 deletions
diff --git a/content/child/fileapi/webfilesystem_impl.cc b/content/child/fileapi/webfilesystem_impl.cc
index 090bf7d..78952b5 100644
--- a/content/child/fileapi/webfilesystem_impl.cc
+++ b/content/child/fileapi/webfilesystem_impl.cc
@@ -9,6 +9,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
+#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_local.h"
#include "content/child/child_thread.h"
#include "content/child/fileapi/file_system_dispatcher.h"
@@ -94,6 +95,35 @@ class CallbacksMap : public WorkerTaskRunner::Observer {
DISALLOW_COPY_AND_ASSIGN(CallbacksMap);
};
+class WaitableCallbackResults {
+ public:
+ static WaitableCallbackResults* MaybeCreate(
+ WebKit::WebFileSystemCallbacks* callbacks) {
+ if (callbacks->shouldBlockUntilCompletion())
+ return new WaitableCallbackResults;
+ return NULL;
+ }
+ ~WaitableCallbackResults() {}
+
+ void SetResultsAndSignal(const base::Closure& results_closure) {
+ results_closure_ = results_closure;
+ event_->Signal();
+ }
+
+ void WaitAndRun() {
+ event_->Wait();
+ DCHECK(!results_closure_.is_null());
+ results_closure_.Run();
+ }
+
+ private:
+ WaitableCallbackResults() : event_(new base::WaitableEvent(true, false)) {}
+
+ base::WaitableEvent* event_;
+ base::Closure results_closure_;
+ DISALLOW_COPY_AND_ASSIGN(WaitableCallbackResults);
+};
+
void DidReceiveSnapshotFile(int request_id) {
if (ChildThread::current())
ChildThread::current()->Send(
@@ -107,67 +137,90 @@ int CurrentWorkerId() {
template <typename Method, typename Params>
void CallDispatcherOnMainThread(
base::MessageLoopProxy* loop,
- Method method, const Params& params) {
+ Method method, const Params& params,
+ scoped_ptr<WaitableCallbackResults> waitable_results) {
+ scoped_ptr<WaitableCallbackResults> null_waitable;
if (!loop->RunsTasksOnCurrentThread()) {
loop->PostTask(FROM_HERE,
base::Bind(&CallDispatcherOnMainThread<Method, Params>,
- make_scoped_refptr(loop), method, params));
- return;
+ make_scoped_refptr(loop), method, params,
+ base::Passed(&null_waitable)));
+ if (!waitable_results)
+ return;
+ waitable_results->WaitAndRun();
}
if (!ChildThread::current() ||
!ChildThread::current()->file_system_dispatcher())
return;
+ DCHECK(!waitable_results);
DispatchToMethod(ChildThread::current()->file_system_dispatcher(),
method, params);
}
+// Run WebFileSystemCallbacks's |method| with |params|.
template <typename Method, typename Params>
-void CallbackFileSystemCallbacks(
- int thread_id, int callbacks_id,
- Method method, const Params& params) {
- if (thread_id != CurrentWorkerId()) {
- WorkerTaskRunner::Instance()->PostTask(
- thread_id,
- base::Bind(&CallbackFileSystemCallbacks<Method, Params>,
- thread_id, callbacks_id, method, params));
- return;
- }
+void RunCallbacks(int callbacks_id, Method method, const Params& params) {
if (!CallbacksMap::Get())
return;
-
WebFileSystemCallbacks* callbacks =
CallbacksMap::Get()->GetAndUnregisterCallbacks(callbacks_id);
DCHECK(callbacks);
DispatchToMethod(callbacks, method, params);
}
+void DispatchResultsClosure(int thread_id, int callbacks_id,
+ WaitableCallbackResults* waitable_results,
+ const base::Closure& results_closure) {
+ if (thread_id != CurrentWorkerId()) {
+ if (waitable_results) {
+ waitable_results->SetResultsAndSignal(results_closure);
+ return;
+ }
+ WorkerTaskRunner::Instance()->PostTask(thread_id, results_closure);
+ return;
+ }
+ results_closure.Run();
+}
+
+template <typename Method, typename Params>
+void CallbackFileSystemCallbacks(
+ int thread_id, int callbacks_id,
+ WaitableCallbackResults* waitable_results,
+ Method method, const Params& params) {
+ DispatchResultsClosure(
+ thread_id, callbacks_id, waitable_results,
+ base::Bind(&RunCallbacks<Method, Params>, callbacks_id, method, params));
+}
+
void StatusCallbackAdapter(int thread_id, int callbacks_id,
+ WaitableCallbackResults* waitable_results,
base::PlatformFileError error) {
if (error == base::PLATFORM_FILE_OK) {
CallbackFileSystemCallbacks(
- thread_id, callbacks_id,
+ thread_id, callbacks_id, waitable_results,
&WebFileSystemCallbacks::didSucceed, MakeTuple());
} else {
CallbackFileSystemCallbacks(
- thread_id, callbacks_id,
+ thread_id, callbacks_id, waitable_results,
&WebFileSystemCallbacks::didFail,
MakeTuple(fileapi::PlatformFileErrorToWebFileError(error)));
}
}
void ReadMetadataCallbackAdapter(int thread_id, int callbacks_id,
+ WaitableCallbackResults* waitable_results,
const base::PlatformFileInfo& file_info) {
WebFileInfo web_file_info;
webkit_glue::PlatformFileInfoToWebFileInfo(file_info, &web_file_info);
CallbackFileSystemCallbacks(
- thread_id, callbacks_id,
+ thread_id, callbacks_id, waitable_results,
&WebFileSystemCallbacks::didReadMetadata,
MakeTuple(web_file_info));
}
void ReadDirectoryCallbackAdapater(
- int thread_id, int callbacks_id,
+ int thread_id, int callbacks_id, WaitableCallbackResults* waitable_results,
const std::vector<fileapi::DirectoryEntry>& entries,
bool has_more) {
WebVector<WebFileSystemEntry> file_system_entries(entries.size());
@@ -177,27 +230,17 @@ void ReadDirectoryCallbackAdapater(
file_system_entries[i].isDirectory = entries[i].is_directory;
}
CallbackFileSystemCallbacks(
- thread_id, callbacks_id,
+ thread_id, callbacks_id, waitable_results,
&WebFileSystemCallbacks::didReadDirectory,
MakeTuple(file_system_entries, has_more));
}
-void CreateFileWriterCallbackAdapter(
- int thread_id, int callbacks_id,
- base::MessageLoopProxy* main_thread_loop,
+void DidCreateFileWriter(
+ int callbacks_id,
const GURL& path,
WebKit::WebFileWriterClient* client,
+ base::MessageLoopProxy* main_thread_loop,
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;
@@ -213,22 +256,25 @@ void CreateFileWriterCallbackAdapter(
new WebFileWriterImpl(path, client, main_thread_loop), file_info.size);
}
-void CreateSnapshotFileCallbackAdapter(
+void CreateFileWriterCallbackAdapter(
int thread_id, int callbacks_id,
+ WaitableCallbackResults* waitable_results,
+ base::MessageLoopProxy* main_thread_loop,
+ const GURL& path,
+ WebKit::WebFileWriterClient* client,
+ const base::PlatformFileInfo& file_info) {
+ DispatchResultsClosure(
+ thread_id, callbacks_id, waitable_results,
+ base::Bind(&DidCreateFileWriter, callbacks_id, path, client,
+ make_scoped_refptr(main_thread_loop), file_info));
+}
+
+void DidCreateSnapshotFile(
+ int callbacks_id,
base::MessageLoopProxy* main_thread_loop,
const base::PlatformFileInfo& file_info,
const base::FilePath& platform_path,
int request_id) {
- if (thread_id != CurrentWorkerId()) {
- WorkerTaskRunner::Instance()->PostTask(
- thread_id,
- base::Bind(&CreateSnapshotFileCallbackAdapter,
- thread_id, callbacks_id,
- make_scoped_refptr(main_thread_loop),
- file_info, platform_path, request_id));
- return;
- }
-
if (!CallbacksMap::Get())
return;
@@ -247,6 +293,20 @@ void CreateSnapshotFileCallbackAdapter(
FROM_HERE, base::Bind(&DidReceiveSnapshotFile, request_id));
}
+void CreateSnapshotFileCallbackAdapter(
+ int thread_id, int callbacks_id,
+ WaitableCallbackResults* waitable_results,
+ base::MessageLoopProxy* main_thread_loop,
+ const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path,
+ int request_id) {
+ DispatchResultsClosure(
+ thread_id, callbacks_id, waitable_results,
+ base::Bind(&DidCreateSnapshotFile, callbacks_id,
+ make_scoped_refptr(main_thread_loop),
+ file_info, platform_path, request_id));
+}
+
} // namespace
WebFileSystemImpl::~WebFileSystemImpl() {
@@ -261,12 +321,16 @@ void WebFileSystemImpl::move(
const WebKit::WebURL& dest_path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::Move,
MakeTuple(GURL(src_path), GURL(dest_path),
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::copy(
@@ -274,50 +338,67 @@ void WebFileSystemImpl::copy(
const WebKit::WebURL& dest_path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::Copy,
MakeTuple(GURL(src_path), GURL(dest_path),
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::remove(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::Remove,
MakeTuple(GURL(path), false /* recursive */,
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::removeRecursively(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::Remove,
MakeTuple(GURL(path), true /* recursive */,
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::readMetadata(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::ReadMetadata,
MakeTuple(GURL(path),
base::Bind(&ReadMetadataCallbackAdapter,
- CurrentWorkerId(), callbacks_id),
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results)),
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::createFile(
@@ -325,12 +406,16 @@ void WebFileSystemImpl::createFile(
bool exclusive,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::CreateFile,
MakeTuple(GURL(path), exclusive,
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::createDirectory(
@@ -338,50 +423,67 @@ void WebFileSystemImpl::createDirectory(
bool exclusive,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::CreateDirectory,
MakeTuple(GURL(path), exclusive, false /* recursive */,
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::fileExists(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::Exists,
MakeTuple(GURL(path), false /* directory */,
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::directoryExists(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::Exists,
MakeTuple(GURL(path), true /* directory */,
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::readDirectory(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::ReadDirectory,
MakeTuple(GURL(path),
base::Bind(&ReadDirectoryCallbackAdapater,
- CurrentWorkerId(), callbacks_id),
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results)),
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
WebKit::WebFileWriter* WebFileSystemImpl::createFileWriter(
@@ -394,30 +496,40 @@ void WebFileSystemImpl::createFileWriter(
WebKit::WebFileWriterClient* client,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::ReadMetadata,
MakeTuple(GURL(path),
base::Bind(&CreateFileWriterCallbackAdapter,
- CurrentWorkerId(), callbacks_id, main_thread_loop_,
- GURL(path), client),
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results),
+ main_thread_loop_, GURL(path), client),
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
void WebFileSystemImpl::createSnapshotFileAndReadMetadata(
const WebKit::WebURL& path,
WebKit::WebFileSystemCallbacks* callbacks) {
int callbacks_id = CallbacksMap::GetOrCreate()->RegisterCallbacks(callbacks);
+ WaitableCallbackResults* waitable_results =
+ WaitableCallbackResults::MaybeCreate(callbacks);
CallDispatcherOnMainThread(
main_thread_loop_.get(),
&FileSystemDispatcher::CreateSnapshotFile,
MakeTuple(GURL(path),
base::Bind(&CreateSnapshotFileCallbackAdapter,
CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results),
main_thread_loop_),
base::Bind(&StatusCallbackAdapter,
- CurrentWorkerId(), callbacks_id)));
+ CurrentWorkerId(), callbacks_id,
+ base::Unretained(waitable_results))),
+ make_scoped_ptr(waitable_results));
}
} // namespace content