Chromium Code Reviews| 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..71e9d5ac76b904e0fbfe174db2bb3059f4399763 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() {} |
| + WaitableCallbackResults() : event_(false /* manual_reset */, |
| + false /* initially_signaled */) {} |
| void SetResultsAndSignal(const base::Closure& results_closure) { |
|
kinuko
2014/03/06 13:12:35
SetResultsAndSignal -> AddResultsAndSignal ?
hashimoto
2014/03/07 02:15:47
Done.
|
| - results_closure_ = results_closure; |
| - event_->Signal(); |
| + { |
| + base::AutoLock lock(lock_); |
| + results_closures_.push_back(results_closure); |
| + } |
| + event_.Signal(); |
| } |
| void WaitAndRun() { |
| { |
| blink::WebHeap::SafePointScope safe_point; |
| - event_->Wait(); |
| + 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); |
| + } |
| + 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 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) { |
| + // If someone is waiting, this should result in running the closure. |
| waitable_results->SetResultsAndSignal(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 |