Index: content/child/fileapi/webfilesystem_impl.cc |
diff --git a/content/child/fileapi/webfilesystem_impl.cc b/content/child/fileapi/webfilesystem_impl.cc |
index c149afd3ff628eb1ab28634122b38720109e6761..67f63581e0e60f3bcc9fb3a6f5a5b8304aab322f 100644 |
--- a/content/child/fileapi/webfilesystem_impl.cc |
+++ b/content/child/fileapi/webfilesystem_impl.cc |
@@ -35,43 +35,56 @@ using blink::WebVector; |
namespace content { |
-namespace { |
- |
-base::LazyInstance<base::ThreadLocalPointer<WebFileSystemImpl> >::Leaky |
- g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER; |
- |
-class WaitableCallbackResults { |
+class WebFileSystemImpl::WaitableCallbackResults |
+ : public base::RefCountedThreadSafe<WaitableCallbackResults> { |
public: |
- static WaitableCallbackResults* MaybeCreate( |
- const WebFileSystemCallbacks& callbacks) { |
- if (callbacks.shouldBlockUntilCompletion()) |
- return new WaitableCallbackResults; |
- return NULL; |
- } |
- ~WaitableCallbackResults() {} |
- |
- void SetResultsAndSignal(const base::Closure& results_closure) { |
- results_closure_ = results_closure; |
- event_->Signal(); |
+ WaitableCallbackResults() |
+ : results_available_event_(true /* manual_reset */, |
+ false /* initially_signaled */) {} |
+ |
+ void AddResultsAndSignal(const base::Closure& results_closure) { |
+ base::AutoLock lock(lock_); |
+ results_closures_.push_back(results_closure); |
+ results_available_event_.Signal(); |
} |
void WaitAndRun() { |
{ |
blink::WebHeap::SafePointScope safe_point; |
- event_->Wait(); |
+ results_available_event_.Wait(); |
} |
- DCHECK(!results_closure_.is_null()); |
- results_closure_.Run(); |
+ Run(); |
+ } |
+ |
+ void Run() { |
+ std::vector<base::Closure> closures; |
+ { |
+ base::AutoLock lock(lock_); |
+ results_closures_.swap(closures); |
+ results_available_event_.Reset(); |
+ } |
+ for (size_t i = 0; i < closures.size(); ++i) |
+ closures[i].Run(); |
} |
private: |
- WaitableCallbackResults() : event_(new base::WaitableEvent(true, false)) {} |
+ friend class base::RefCountedThreadSafe<WaitableCallbackResults>; |
- base::WaitableEvent* event_; |
- base::Closure results_closure_; |
+ ~WaitableCallbackResults() {} |
+ |
+ base::Lock lock_; |
+ base::WaitableEvent results_available_event_; |
+ std::vector<base::Closure> results_closures_; |
DISALLOW_COPY_AND_ASSIGN(WaitableCallbackResults); |
}; |
+namespace { |
+ |
+typedef WebFileSystemImpl::WaitableCallbackResults WaitableCallbackResults; |
+ |
+base::LazyInstance<base::ThreadLocalPointer<WebFileSystemImpl> >::Leaky |
+ g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER; |
+ |
void DidReceiveSnapshotFile(int request_id) { |
if (ChildThread::current()) |
ChildThread::current()->Send( |
@@ -86,13 +99,12 @@ template <typename Method, typename Params> |
void CallDispatcherOnMainThread( |
base::MessageLoopProxy* loop, |
Method method, const Params& params, |
- scoped_ptr<WaitableCallbackResults> waitable_results) { |
- scoped_ptr<WaitableCallbackResults> null_waitable; |
+ WaitableCallbackResults* waitable_results) { |
if (!loop->RunsTasksOnCurrentThread()) { |
loop->PostTask(FROM_HERE, |
base::Bind(&CallDispatcherOnMainThread<Method, Params>, |
make_scoped_refptr(loop), method, params, |
- base::Passed(&null_waitable))); |
+ scoped_refptr<WaitableCallbackResults>())); |
if (!waitable_results) |
return; |
waitable_results->WaitAndRun(); |
@@ -106,15 +118,22 @@ void CallDispatcherOnMainThread( |
method, params); |
} |
+enum CallbacksUnregisterMode { |
+ UNREGISTER_CALLBACKS, |
+ DO_NOT_UNREGISTER_CALLBACKS, |
+}; |
+ |
// Run WebFileSystemCallbacks's |method| with |params|. |
template <typename Method, typename Params> |
-void RunCallbacks(int callbacks_id, Method method, const Params& params) { |
+void RunCallbacks(int callbacks_id, Method method, const Params& params, |
+ CallbacksUnregisterMode callbacks_unregister_mode) { |
WebFileSystemImpl* filesystem = |
WebFileSystemImpl::ThreadSpecificInstance(NULL); |
if (!filesystem) |
return; |
- WebFileSystemCallbacks callbacks = |
- filesystem->GetAndUnregisterCallbacks(callbacks_id); |
+ WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id); |
+ if (callbacks_unregister_mode == UNREGISTER_CALLBACKS) |
+ filesystem->UnregisterCallbacks(callbacks_id); |
DispatchToMethod(&callbacks, method, params); |
} |
@@ -123,7 +142,13 @@ void DispatchResultsClosure(int thread_id, int callbacks_id, |
const base::Closure& results_closure) { |
if (thread_id != CurrentWorkerId()) { |
if (waitable_results) { |
- waitable_results->SetResultsAndSignal(results_closure); |
+ // If someone is waiting, this should result in running the closure. |
+ waitable_results->AddResultsAndSignal(results_closure); |
+ // In case no one is waiting, post a task to run the closure. |
+ WorkerTaskRunner::Instance()->PostTask( |
+ thread_id, |
+ base::Bind(&WaitableCallbackResults::Run, |
+ make_scoped_refptr(waitable_results))); |
return; |
} |
WorkerTaskRunner::Instance()->PostTask(thread_id, results_closure); |
@@ -136,10 +161,12 @@ template <typename Method, typename Params> |
void CallbackFileSystemCallbacks( |
int thread_id, int callbacks_id, |
WaitableCallbackResults* waitable_results, |
- Method method, const Params& params) { |
+ Method method, const Params& params, |
+ CallbacksUnregisterMode callbacks_unregister_mode) { |
DispatchResultsClosure( |
thread_id, callbacks_id, waitable_results, |
- base::Bind(&RunCallbacks<Method, Params>, callbacks_id, method, params)); |
+ base::Bind(&RunCallbacks<Method, Params>, callbacks_id, method, params, |
+ callbacks_unregister_mode)); |
} |
//----------------------------------------------------------------------------- |
@@ -154,7 +181,8 @@ void OpenFileSystemCallbackAdapter( |
CallbackFileSystemCallbacks( |
thread_id, callbacks_id, waitable_results, |
&WebFileSystemCallbacks::didOpenFileSystem, |
- MakeTuple(base::UTF8ToUTF16(name), root)); |
+ MakeTuple(base::UTF8ToUTF16(name), root), |
+ UNREGISTER_CALLBACKS); |
} |
void ResolveURLCallbackAdapter( |
@@ -169,7 +197,8 @@ void ResolveURLCallbackAdapter( |
&WebFileSystemCallbacks::didResolveURL, |
MakeTuple(base::UTF8ToUTF16(info.name), info.root_url, |
static_cast<blink::WebFileSystemType>(info.mount_type), |
- normalized_path.AsUTF16Unsafe(), is_directory)); |
+ normalized_path.AsUTF16Unsafe(), is_directory), |
+ UNREGISTER_CALLBACKS); |
} |
void StatusCallbackAdapter(int thread_id, int callbacks_id, |
@@ -178,12 +207,14 @@ void StatusCallbackAdapter(int thread_id, int callbacks_id, |
if (error == base::File::FILE_OK) { |
CallbackFileSystemCallbacks( |
thread_id, callbacks_id, waitable_results, |
- &WebFileSystemCallbacks::didSucceed, MakeTuple()); |
+ &WebFileSystemCallbacks::didSucceed, MakeTuple(), |
+ UNREGISTER_CALLBACKS); |
} else { |
CallbackFileSystemCallbacks( |
thread_id, callbacks_id, waitable_results, |
&WebFileSystemCallbacks::didFail, |
- MakeTuple(fileapi::FileErrorToWebFileError(error))); |
+ MakeTuple(fileapi::FileErrorToWebFileError(error)), |
+ UNREGISTER_CALLBACKS); |
} |
} |
@@ -195,10 +226,11 @@ void ReadMetadataCallbackAdapter(int thread_id, int callbacks_id, |
CallbackFileSystemCallbacks( |
thread_id, callbacks_id, waitable_results, |
&WebFileSystemCallbacks::didReadMetadata, |
- MakeTuple(web_file_info)); |
+ MakeTuple(web_file_info), |
+ UNREGISTER_CALLBACKS); |
} |
-void ReadDirectoryCallbackAdapater( |
+void ReadDirectoryCallbackAdapter( |
int thread_id, int callbacks_id, WaitableCallbackResults* waitable_results, |
const std::vector<fileapi::DirectoryEntry>& entries, |
bool has_more) { |
@@ -211,7 +243,8 @@ void ReadDirectoryCallbackAdapater( |
CallbackFileSystemCallbacks( |
thread_id, callbacks_id, waitable_results, |
&WebFileSystemCallbacks::didReadDirectory, |
- MakeTuple(file_system_entries, has_more)); |
+ MakeTuple(file_system_entries, has_more), |
+ has_more ? DO_NOT_UNREGISTER_CALLBACKS : UNREGISTER_CALLBACKS); |
} |
void DidCreateFileWriter( |
@@ -225,8 +258,8 @@ void DidCreateFileWriter( |
if (!filesystem) |
return; |
- WebFileSystemCallbacks callbacks = |
- filesystem->GetAndUnregisterCallbacks(callbacks_id); |
+ WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id); |
+ filesystem->UnregisterCallbacks(callbacks_id); |
if (file_info.is_directory || file_info.size < 0) { |
callbacks.didFail(blink::WebFileErrorInvalidState); |
@@ -264,8 +297,8 @@ void DidCreateSnapshotFile( |
if (!filesystem) |
return; |
- WebFileSystemCallbacks callbacks = |
- filesystem->GetAndUnregisterCallbacks(callbacks_id); |
+ WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id); |
+ filesystem->UnregisterCallbacks(callbacks_id); |
WebFileInfo web_file_info; |
FileInfoToWebFileInfo(file_info, &web_file_info); |
@@ -315,7 +348,7 @@ void WebFileSystemImpl::DeleteThreadSpecificInstance() { |
WebFileSystemImpl::WebFileSystemImpl(base::MessageLoopProxy* main_thread_loop) |
: main_thread_loop_(main_thread_loop), |
- next_callbacks_id_(0) { |
+ next_callbacks_id_(1) { |
g_webfilesystem_tls.Pointer()->Set(this); |
} |
@@ -332,39 +365,35 @@ void WebFileSystemImpl::openFileSystem( |
blink::WebFileSystemType type, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::OpenFileSystem, |
MakeTuple(GURL(storage_partition), |
static_cast<fileapi::FileSystemType>(type), |
base::Bind(&OpenFileSystemCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results)), |
+ CurrentWorkerId(), callbacks_id, waitable_results), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::resolveURL( |
const blink::WebURL& filesystem_url, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::ResolveURL, |
MakeTuple(GURL(filesystem_url), |
base::Bind(&ResolveURLCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results)), |
+ CurrentWorkerId(), callbacks_id, waitable_results), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::deleteFileSystem( |
@@ -372,17 +401,16 @@ void WebFileSystemImpl::deleteFileSystem( |
blink::WebFileSystemType type, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::DeleteFileSystem, |
MakeTuple(GURL(storage_partition), |
static_cast<fileapi::FileSystemType>(type), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::move( |
@@ -390,16 +418,15 @@ void WebFileSystemImpl::move( |
const blink::WebURL& dest_path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::Move, |
MakeTuple(GURL(src_path), GURL(dest_path), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::copy( |
@@ -407,67 +434,62 @@ void WebFileSystemImpl::copy( |
const blink::WebURL& dest_path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::Copy, |
MakeTuple(GURL(src_path), GURL(dest_path), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::remove( |
const blink::WebURL& path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::Remove, |
MakeTuple(GURL(path), false /* recursive */, |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::removeRecursively( |
const blink::WebURL& path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::Remove, |
MakeTuple(GURL(path), true /* recursive */, |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::readMetadata( |
const blink::WebURL& path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::ReadMetadata, |
MakeTuple(GURL(path), |
base::Bind(&ReadMetadataCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results)), |
+ CurrentWorkerId(), callbacks_id, waitable_results), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::createFile( |
@@ -475,16 +497,15 @@ void WebFileSystemImpl::createFile( |
bool exclusive, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::CreateFile, |
MakeTuple(GURL(path), exclusive, |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::createDirectory( |
@@ -492,67 +513,65 @@ void WebFileSystemImpl::createDirectory( |
bool exclusive, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::CreateDirectory, |
MakeTuple(GURL(path), exclusive, false /* recursive */, |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::fileExists( |
const blink::WebURL& path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::Exists, |
MakeTuple(GURL(path), false /* directory */, |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::directoryExists( |
const blink::WebURL& path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::Exists, |
MakeTuple(GURL(path), true /* directory */, |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
-void WebFileSystemImpl::readDirectory( |
+READ_DIRECTORY_RETURN_TYPE WebFileSystemImpl::readDirectory( |
const blink::WebURL& path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::ReadDirectory, |
MakeTuple(GURL(path), |
- base::Bind(&ReadDirectoryCallbackAdapater, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results)), |
+ base::Bind(&ReadDirectoryCallbackAdapter, |
+ CurrentWorkerId(), callbacks_id, waitable_results), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
-base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
+#if defined(READ_DIRECTORY_RETURNS_INT) |
+ return callbacks_id; |
+#endif |
} |
void WebFileSystemImpl::createFileWriter( |
@@ -560,40 +579,46 @@ void WebFileSystemImpl::createFileWriter( |
blink::WebFileWriterClient* client, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::ReadMetadata, |
MakeTuple(GURL(path), |
base::Bind(&CreateFileWriterCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results), |
+ CurrentWorkerId(), callbacks_id, waitable_results, |
main_thread_loop_, GURL(path), client), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
} |
void WebFileSystemImpl::createSnapshotFileAndReadMetadata( |
const blink::WebURL& path, |
WebFileSystemCallbacks callbacks) { |
int callbacks_id = RegisterCallbacks(callbacks); |
- WaitableCallbackResults* waitable_results = |
- WaitableCallbackResults::MaybeCreate(callbacks); |
+ scoped_refptr<WaitableCallbackResults> waitable_results = |
+ MaybeCreateWaitableResults(callbacks, callbacks_id); |
CallDispatcherOnMainThread( |
main_thread_loop_.get(), |
&FileSystemDispatcher::CreateSnapshotFile, |
MakeTuple(GURL(path), |
base::Bind(&CreateSnapshotFileCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results), |
+ CurrentWorkerId(), callbacks_id, waitable_results, |
main_thread_loop_), |
base::Bind(&StatusCallbackAdapter, |
- CurrentWorkerId(), callbacks_id, |
- base::Unretained(waitable_results))), |
- make_scoped_ptr(waitable_results)); |
+ CurrentWorkerId(), callbacks_id, waitable_results)), |
+ waitable_results.get()); |
+} |
+ |
+bool WebFileSystemImpl::waitForAdditionalResult(int callbacksId) { |
+ WaitableCallbackResultsMap::iterator found = |
+ waitable_results_.find(callbacksId); |
+ if (found == waitable_results_.end()) |
+ return false; |
+ |
+ found->second->WaitAndRun(); |
+ return true; |
} |
int WebFileSystemImpl::RegisterCallbacks( |
@@ -604,14 +629,29 @@ int WebFileSystemImpl::RegisterCallbacks( |
return id; |
} |
-WebFileSystemCallbacks WebFileSystemImpl::GetAndUnregisterCallbacks( |
- int callbacks_id) { |
+WebFileSystemCallbacks WebFileSystemImpl::GetCallbacks(int callbacks_id) { |
+ DCHECK(CalledOnValidThread()); |
+ CallbacksMap::iterator found = callbacks_.find(callbacks_id); |
+ DCHECK(found != callbacks_.end()); |
+ return found->second; |
+} |
+ |
+void WebFileSystemImpl::UnregisterCallbacks(int callbacks_id) { |
DCHECK(CalledOnValidThread()); |
CallbacksMap::iterator found = callbacks_.find(callbacks_id); |
DCHECK(found != callbacks_.end()); |
- WebFileSystemCallbacks callbacks = found->second; |
callbacks_.erase(found); |
- return callbacks; |
+ |
+ waitable_results_.erase(callbacks_id); |
+} |
+ |
+WaitableCallbackResults* WebFileSystemImpl::MaybeCreateWaitableResults( |
+ const WebFileSystemCallbacks& callbacks, int callbacks_id) { |
+ if (!callbacks.shouldBlockUntilCompletion()) |
+ return NULL; |
+ WaitableCallbackResults* results = new WaitableCallbackResults(); |
+ waitable_results_[callbacks_id] = results; |
+ return results; |
} |
} // namespace content |