| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/child/fileapi/webfilewriter_impl.h" | 5 #include "content/child/fileapi/webfilewriter_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/synchronization/waitable_event.h" | 8 #include "base/synchronization/waitable_event.h" |
| 9 #include "base/thread_task_runner_handle.h" |
| 9 #include "content/child/child_thread_impl.h" | 10 #include "content/child/child_thread_impl.h" |
| 10 #include "content/child/fileapi/file_system_dispatcher.h" | 11 #include "content/child/fileapi/file_system_dispatcher.h" |
| 11 #include "content/child/worker_task_runner.h" | 12 #include "content/child/worker_task_runner.h" |
| 12 | 13 |
| 13 namespace content { | 14 namespace content { |
| 14 | 15 |
| 15 namespace { | 16 namespace { |
| 16 | 17 |
| 17 FileSystemDispatcher* GetFileSystemDispatcher() { | 18 FileSystemDispatcher* GetFileSystemDispatcher() { |
| 18 return ChildThreadImpl::current() ? | 19 return ChildThreadImpl::current() ? |
| 19 ChildThreadImpl::current()->file_system_dispatcher() : NULL; | 20 ChildThreadImpl::current()->file_system_dispatcher() : NULL; |
| 20 } | 21 } |
| 21 | 22 |
| 22 } // namespace | 23 } // namespace |
| 23 | 24 |
| 24 typedef FileSystemDispatcher::StatusCallback StatusCallback; | 25 typedef FileSystemDispatcher::StatusCallback StatusCallback; |
| 25 typedef FileSystemDispatcher::WriteCallback WriteCallback; | 26 typedef FileSystemDispatcher::WriteCallback WriteCallback; |
| 26 | 27 |
| 27 // This instance may be created outside main thread but runs mainly | 28 // This instance may be created outside main thread but runs mainly |
| 28 // on main thread. | 29 // on main thread. |
| 29 class WebFileWriterImpl::WriterBridge | 30 class WebFileWriterImpl::WriterBridge |
| 30 : public base::RefCountedThreadSafe<WriterBridge> { | 31 : public base::RefCountedThreadSafe<WriterBridge> { |
| 31 public: | 32 public: |
| 32 WriterBridge(WebFileWriterImpl::Type type) | 33 WriterBridge(WebFileWriterImpl::Type type) |
| 33 : request_id_(0), | 34 : request_id_(0), |
| 34 thread_id_(WorkerTaskRunner::Instance()->CurrentWorkerId()), | 35 running_on_worker_(WorkerTaskRunner::Instance()->CurrentWorkerId() > 0), |
| 36 task_runner_(running_on_worker_ ? base::ThreadTaskRunnerHandle::Get() |
| 37 : nullptr), |
| 35 written_bytes_(0) { | 38 written_bytes_(0) { |
| 36 if (type == WebFileWriterImpl::TYPE_SYNC) | 39 if (type == WebFileWriterImpl::TYPE_SYNC) |
| 37 waitable_event_.reset(new base::WaitableEvent(false, false)); | 40 waitable_event_.reset(new base::WaitableEvent(false, false)); |
| 38 } | 41 } |
| 39 | 42 |
| 40 void Truncate(const GURL& path, int64 offset, | 43 void Truncate(const GURL& path, int64 offset, |
| 41 const StatusCallback& status_callback) { | 44 const StatusCallback& status_callback) { |
| 42 status_callback_ = status_callback; | 45 status_callback_ = status_callback; |
| 43 if (!GetFileSystemDispatcher()) | 46 if (!GetFileSystemDispatcher()) |
| 44 return; | 47 return; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 return; | 92 return; |
| 90 PostTaskToWorker(base::Bind(write_callback_, written_bytes_, complete)); | 93 PostTaskToWorker(base::Bind(write_callback_, written_bytes_, complete)); |
| 91 } | 94 } |
| 92 | 95 |
| 93 void DidFinish(base::File::Error status) { | 96 void DidFinish(base::File::Error status) { |
| 94 PostTaskToWorker(base::Bind(status_callback_, status)); | 97 PostTaskToWorker(base::Bind(status_callback_, status)); |
| 95 } | 98 } |
| 96 | 99 |
| 97 void PostTaskToWorker(const base::Closure& closure) { | 100 void PostTaskToWorker(const base::Closure& closure) { |
| 98 written_bytes_ = 0; | 101 written_bytes_ = 0; |
| 99 if (!thread_id_) { | 102 if (!running_on_worker_) { |
| 100 DCHECK(!waitable_event_); | 103 DCHECK(!waitable_event_); |
| 101 closure.Run(); | 104 closure.Run(); |
| 102 return; | 105 return; |
| 103 } | 106 } |
| 107 DCHECK(task_runner_); |
| 104 if (waitable_event_) { | 108 if (waitable_event_) { |
| 105 results_closure_ = closure; | 109 results_closure_ = closure; |
| 106 waitable_event_->Signal(); | 110 waitable_event_->Signal(); |
| 107 return; | 111 return; |
| 108 } | 112 } |
| 109 WorkerTaskRunner::Instance()->PostTask(thread_id_, closure); | 113 task_runner_->PostTask(FROM_HERE, closure); |
| 110 } | 114 } |
| 111 | 115 |
| 112 StatusCallback status_callback_; | 116 StatusCallback status_callback_; |
| 113 WriteCallback write_callback_; | 117 WriteCallback write_callback_; |
| 114 int request_id_; | 118 int request_id_; |
| 115 int thread_id_; | 119 const bool running_on_worker_; |
| 120 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 116 int written_bytes_; | 121 int written_bytes_; |
| 117 scoped_ptr<base::WaitableEvent> waitable_event_; | 122 scoped_ptr<base::WaitableEvent> waitable_event_; |
| 118 base::Closure results_closure_; | 123 base::Closure results_closure_; |
| 119 }; | 124 }; |
| 120 | 125 |
| 121 WebFileWriterImpl::WebFileWriterImpl( | 126 WebFileWriterImpl::WebFileWriterImpl( |
| 122 const GURL& path, blink::WebFileWriterClient* client, | 127 const GURL& path, blink::WebFileWriterClient* client, |
| 123 Type type, | 128 Type type, |
| 124 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner) | 129 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner) |
| 125 : WebFileWriterBase(path, client), | 130 : WebFileWriterBase(path, client), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 154 DCHECK(!bridge_->waitable_event()); | 159 DCHECK(!bridge_->waitable_event()); |
| 155 closure.Run(); | 160 closure.Run(); |
| 156 return; | 161 return; |
| 157 } | 162 } |
| 158 main_thread_task_runner_->PostTask(FROM_HERE, closure); | 163 main_thread_task_runner_->PostTask(FROM_HERE, closure); |
| 159 if (bridge_->waitable_event()) | 164 if (bridge_->waitable_event()) |
| 160 bridge_->WaitAndRun(); | 165 bridge_->WaitAndRun(); |
| 161 } | 166 } |
| 162 | 167 |
| 163 } // namespace content | 168 } // namespace content |
| OLD | NEW |