| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/location.h" | 6 #include "base/location.h" |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
| 9 #include "base/thread_task_runner_handle.h" | 9 #include "base/thread_task_runner_handle.h" |
| 10 #include "chrome/browser/chromeos/file_system_provider/queue.h" | 10 #include "chrome/browser/chromeos/file_system_provider/queue.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 CHECK(token != task.token); | 43 CHECK(token != task.token); |
| 44 } | 44 } |
| 45 #endif | 45 #endif |
| 46 pending_.push_back(Task(token, callback)); | 46 pending_.push_back(Task(token, callback)); |
| 47 base::ThreadTaskRunnerHandle::Get()->PostTask( | 47 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 48 FROM_HERE, base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); | 48 FROM_HERE, base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); |
| 49 } | 49 } |
| 50 | 50 |
| 51 void Queue::Complete(size_t token) { | 51 void Queue::Complete(size_t token) { |
| 52 const auto it = executed_.find(token); | 52 const auto it = executed_.find(token); |
| 53 CHECK(it != executed_.end()); | 53 DCHECK(it != executed_.end()); |
| 54 completed_[token] = it->second; | |
| 55 executed_.erase(it); | 54 executed_.erase(it); |
| 56 } | |
| 57 | |
| 58 void Queue::Remove(size_t token) { | |
| 59 const auto it = completed_.find(token); | |
| 60 if (it != completed_.end()) { | |
| 61 completed_.erase(it); | |
| 62 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 63 FROM_HERE, | |
| 64 base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); | |
| 65 return; | |
| 66 } | |
| 67 | |
| 68 // If not completed, then it must have been aborted. | |
| 69 const auto aborted_it = aborted_.find(token); | |
| 70 CHECK(aborted_it != aborted_.end()); | |
| 71 aborted_.erase(aborted_it); | |
| 72 | |
| 73 base::ThreadTaskRunnerHandle::Get()->PostTask( | 55 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 74 FROM_HERE, base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); | 56 FROM_HERE, base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); |
| 75 } | 57 } |
| 76 | 58 |
| 77 void Queue::MaybeRun() { | 59 void Queue::MaybeRun() { |
| 78 if (executed_.size() + completed_.size() == max_in_parallel_ || | 60 if (executed_.size() == max_in_parallel_ || !pending_.size()) |
| 79 !pending_.size()) { | |
| 80 return; | 61 return; |
| 81 } | |
| 82 | 62 |
| 83 CHECK_GT(max_in_parallel_, executed_.size() + completed_.size()); | 63 CHECK_GT(max_in_parallel_, executed_.size()); |
| 84 Task task = pending_.front(); | 64 Task task = pending_.front(); |
| 85 pending_.pop_front(); | 65 pending_.pop_front(); |
| 86 | 66 |
| 87 executed_[task.token] = task; | 67 executed_[task.token] = task; |
| 88 AbortCallback abort_callback = task.callback.Run(); | 68 AbortCallback abort_callback = task.callback.Run(); |
| 89 | 69 |
| 90 // It may happen that the task is completed and removed synchronously. Hence, | 70 // It may happen that the task is completed and removed synchronously. Hence, |
| 91 // we need to check if the task is still in the executed collection. | 71 // we need to check if the task is still in the executed collection. |
| 92 const auto executed_task_it = executed_.find(task.token); | 72 const auto executed_task_it = executed_.find(task.token); |
| 93 if (executed_task_it != executed_.end()) | 73 if (executed_task_it != executed_.end()) |
| 94 executed_task_it->second.abort_callback = abort_callback; | 74 executed_task_it->second.abort_callback = abort_callback; |
| 95 } | 75 } |
| 96 | 76 |
| 97 void Queue::Abort(size_t token) { | 77 void Queue::Abort(size_t token) { |
| 98 // Check if it's running. | 78 // Check if it's running. If so, then abort and expect a Complete() call soon. |
| 99 const auto it = executed_.find(token); | 79 const auto it = executed_.find(token); |
| 100 if (it != executed_.end()) { | 80 if (it != executed_.end()) { |
| 101 Task task = it->second; | 81 Task& task = it->second; |
| 102 aborted_[token] = task; | 82 AbortCallback abort_callback = task.abort_callback; |
| 103 executed_.erase(it); | 83 task.abort_callback = AbortCallback(); |
| 104 CHECK(!task.abort_callback.is_null()); | 84 DCHECK(!abort_callback.is_null()); |
| 105 task.abort_callback.Run(); | 85 abort_callback.Run(); |
| 106 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 107 FROM_HERE, | |
| 108 base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); | |
| 109 return; | 86 return; |
| 110 } | 87 } |
| 111 | 88 |
| 112 // Aborting not running tasks is linear. TODO(mtomasz): Optimize if feasible. | 89 // Aborting not running tasks is linear. TODO(mtomasz): Optimize if feasible. |
| 113 for (auto it = pending_.begin(); it != pending_.end(); ++it) { | 90 for (auto it = pending_.begin(); it != pending_.end(); ++it) { |
| 114 if (token == it->token) { | 91 if (token == it->token) { |
| 115 aborted_[token] = *it; | |
| 116 pending_.erase(it); | 92 pending_.erase(it); |
| 117 base::ThreadTaskRunnerHandle::Get()->PostTask( | 93 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 118 FROM_HERE, | 94 FROM_HERE, |
| 119 base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); | 95 base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr())); |
| 120 return; | 96 return; |
| 121 } | 97 } |
| 122 } | 98 } |
| 123 | 99 |
| 124 // The task is already removed, marked as completed or aborted. | 100 // The task is already removed, marked as completed or aborted. |
| 125 NOTREACHED(); | 101 NOTREACHED(); |
| 126 } | 102 } |
| 127 | 103 |
| 128 bool Queue::IsAborted(size_t token) { | |
| 129 #if !NDEBUG | |
| 130 bool in_queue = executed_.find(token) != executed_.end() || | |
| 131 completed_.find(token) != completed_.end() || | |
| 132 aborted_.find(token) != aborted_.end(); | |
| 133 for (auto& task : pending_) { | |
| 134 if (token == task.token) { | |
| 135 in_queue = true; | |
| 136 break; | |
| 137 } | |
| 138 } | |
| 139 DCHECK(in_queue); | |
| 140 #endif | |
| 141 return aborted_.find(token) != aborted_.end(); | |
| 142 } | |
| 143 | |
| 144 } // namespace file_system_provider | 104 } // namespace file_system_provider |
| 145 } // namespace chromeos | 105 } // namespace chromeos |
| OLD | NEW |