Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(703)

Unified Diff: chrome/browser/chromeos/file_system_provider/queue.cc

Issue 829553002: [fsp] Add throttling for number of opened files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/file_system_provider/queue.cc
diff --git a/chrome/browser/chromeos/file_system_provider/queue.cc b/chrome/browser/chromeos/file_system_provider/queue.cc
new file mode 100644
index 0000000000000000000000000000000000000000..75032081857c64f44fbc525b3ae8b885f4b72011
--- /dev/null
+++ b/chrome/browser/chromeos/file_system_provider/queue.cc
@@ -0,0 +1,119 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "chrome/browser/chromeos/file_system_provider/queue.h"
+
+namespace chromeos {
+namespace file_system_provider {
+
+struct Queue::Task {
+ Task() : token(0), completed(false) {}
+ Task(size_t token, const AbortableCallback& callback)
+ : token(token), completed(false), callback(callback) {}
+
+ size_t token;
+ bool completed;
+ AbortableCallback callback;
+ AbortCallback abort_callback;
+};
+
+Queue::Queue(size_t max_in_parallel)
+ : max_in_parallel_(max_in_parallel),
+ next_token_(1),
+ weak_ptr_factory_(this) {
+ DCHECK_LT(0u, max_in_parallel);
+}
+
+Queue::~Queue() {
+}
+
+size_t Queue::NewToken() {
+ return next_token_++;
+}
+
+AbortCallback Queue::Enqueue(size_t token, const AbortableCallback& callback) {
+#if !NDEBUG
+ const auto it = executed_.find(token);
+ DCHECK(it == executed_.end());
+ for (auto& task : pending_) {
+ DCHECK(token != task.token);
+ }
+#endif
+ pending_.push_back(Task(token, callback));
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr()));
+ return base::Bind(&Queue::Abort, weak_ptr_factory_.GetWeakPtr(), token);
+}
+
+void Queue::Complete(size_t token) {
+ const auto it = executed_.find(token);
+ DCHECK(it != executed_.end() && !it->second.completed);
+ it->second.completed = true;
+}
+
+void Queue::Remove(size_t token) {
+ const auto it = executed_.find(token);
+ DCHECK(it != executed_.end() && it->second.completed);
+
+ executed_.erase(it);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void Queue::MaybeRun() {
+ if (executed_.size() == max_in_parallel_ || !pending_.size()) {
+ return;
+ }
+
+ DCHECK_GT(max_in_parallel_, executed_.size());
+ Task task = pending_.front();
+ pending_.pop_front();
+
+ executed_[task.token] = task;
+ executed_[task.token].abort_callback = task.callback.Run();
+}
+
+void Queue::Abort(size_t token,
+ const storage::AsyncFileUtil::StatusCallback& callback) {
+ // Check if it's running.
+ const auto it = executed_.find(token);
+ if (it != executed_.end()) {
+ const Task& task = it->second;
+ // If the task is marked as completed, then it's impossible to abort it.
+ if (task.completed) {
+ callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
+ return;
+ }
+ DCHECK(!task.abort_callback.is_null());
+ it->second.abort_callback.Run(callback);
+ executed_.erase(it);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr()));
+ return;
+ }
+
+ // Aborting not running tasks is linear. TODO(mtomasz): Optimize if feasible.
+ for (auto it = pending_.begin(); it != pending_.end(); ++it) {
+ if (token == it->token) {
+ pending_.erase(it);
+ callback.Run(base::File::FILE_OK);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&Queue::MaybeRun, weak_ptr_factory_.GetWeakPtr()));
+ return;
+ }
+ }
+
+ // The task is already removed.
+ callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
+}
+
+} // namespace file_system_provider
+} // namespace chromeos
« no previous file with comments | « chrome/browser/chromeos/file_system_provider/queue.h ('k') | chrome/browser/chromeos/file_system_provider/queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698