summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorlevin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-26 06:09:38 +0000
committerlevin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-26 06:09:38 +0000
commit6fd0ca52fbb5d33e3355c0ebe8fe81219be90de0 (patch)
tree6a24baf9874440f81fde368ab964ffc0d912c2d5 /base
parentb924ae04055aa82cd19ef522b690e3cd66352c11 (diff)
downloadchromium_src-6fd0ca52fbb5d33e3355c0ebe8fe81219be90de0.zip
chromium_src-6fd0ca52fbb5d33e3355c0ebe8fe81219be90de0.tar.gz
chromium_src-6fd0ca52fbb5d33e3355c0ebe8fe81219be90de0.tar.bz2
Move task_queue.* to base because it makes more sense there.
TEST=base_test --gtest_filter=TaskQueue*.* (added in this patch). BUG=38475 Review URL: http://codereview.chromium.org/3205004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57479 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/base.gyp1
-rw-r--r--base/base.gypi2
-rw-r--r--base/task_queue.cc49
-rw-r--r--base/task_queue.h43
-rw-r--r--base/task_queue_unittest.cc147
5 files changed, 242 insertions, 0 deletions
diff --git a/base/base.gyp b/base/base.gyp
index 23e8c6b..d3ac910 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -144,6 +144,7 @@
'sys_info_unittest.cc',
'sys_string_conversions_mac_unittest.mm',
'sys_string_conversions_unittest.cc',
+ 'task_queue_unittest.cc',
'thread_checker_unittest.cc',
'thread_collision_warner_unittest.cc',
'thread_local_storage_unittest.cc',
diff --git a/base/base.gypi b/base/base.gypi
index 2a6e64a..383e45d 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -253,6 +253,8 @@
'sys_string_conversions_win.cc',
'task.cc',
'task.h',
+ 'task_queue.cc',
+ 'task_queue.h',
'template_util.h',
'thread.cc',
'thread.h',
diff --git a/base/task_queue.cc b/base/task_queue.cc
new file mode 100644
index 0000000..e3c196b
--- /dev/null
+++ b/base/task_queue.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2010 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/task_queue.h"
+
+#include "base/logging.h"
+#include "base/stl_util-inl.h"
+
+TaskQueue::TaskQueue() {
+}
+
+TaskQueue::~TaskQueue() {
+ // We own all the pointes in |queue_|. It is our job to delete them.
+ STLDeleteElements(&queue_);
+}
+
+void TaskQueue::Run() {
+ // Nothing to run if our queue is empty.
+ if (queue_.empty())
+ return;
+
+ std::deque<Task*> ready;
+ queue_.swap(ready);
+
+ // Run the tasks that are ready.
+ std::deque<Task*>::const_iterator task;
+ for (task = ready.begin(); task != ready.end(); ++task) {
+ // Run the task and then delete it.
+ (*task)->Run();
+ delete (*task);
+ }
+}
+
+void TaskQueue::Push(Task* task) {
+ DCHECK(task);
+
+ // Add the task to the back of the queue.
+ queue_.push_back(task);
+}
+
+void TaskQueue::Clear() {
+ // Delete all the elements in the queue and clear the dead pointers.
+ STLDeleteElements(&queue_);
+}
+
+bool TaskQueue::IsEmpty() const {
+ return queue_.empty();
+}
diff --git a/base/task_queue.h b/base/task_queue.h
new file mode 100644
index 0000000..5bfc777
--- /dev/null
+++ b/base/task_queue.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 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.
+
+#ifndef BASE_TASK_QUEUE_H_
+#define BASE_TASK_QUEUE_H_
+#pragma once
+
+#include <deque>
+
+#include "base/task.h"
+
+// A TaskQueue is a queue of tasks waiting to be run. To run the tasks, call
+// the Run method. A task queue is itself a Task so that it can be placed in a
+// message loop or another task queue.
+class TaskQueue : public Task {
+ public:
+ TaskQueue();
+ ~TaskQueue();
+
+ // Run all the tasks in the queue. New tasks pushed onto the queue during
+ // a run will be run next time |Run| is called.
+ virtual void Run();
+
+ // Push the specified task onto the queue. When the queue is run, the tasks
+ // will be run in the order they are pushed.
+ //
+ // This method takes ownership of |task| and will delete task after it is run
+ // (or when the TaskQueue is destroyed, if we never got a chance to run it).
+ void Push(Task* task);
+
+ // Remove all tasks from the queue. The tasks are deleted.
+ void Clear();
+
+ // Returns true if this queue contains no tasks.
+ bool IsEmpty() const;
+
+ private:
+ // The list of tasks we are waiting to run.
+ std::deque<Task*> queue_;
+};
+
+#endif // BASE_TASK_QUEUE_H_
diff --git a/base/task_queue_unittest.cc b/base/task_queue_unittest.cc
new file mode 100644
index 0000000..90fc4cd
--- /dev/null
+++ b/base/task_queue_unittest.cc
@@ -0,0 +1,147 @@
+// Copyright (c) 2010 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/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/task.h"
+#include "base/task_queue.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// Sets bools according to whether Run or the destructor were called.
+class TrackCallsTask : public Task {
+ public:
+ TrackCallsTask(bool* ran, bool* deleted)
+ : ran_(ran),
+ deleted_(deleted) {
+ *ran_ = false;
+ *deleted_ = false;
+ }
+
+ virtual ~TrackCallsTask() {
+ *deleted_ = true;
+ }
+
+ virtual void Run() {
+ *ran_ = true;
+ }
+
+ private:
+ bool* ran_;
+ bool* deleted_;
+
+ DISALLOW_COPY_AND_ASSIGN(TrackCallsTask);
+};
+
+// Adds a given task to the queue when run.
+class TaskQueuerTask : public Task {
+ public:
+ TaskQueuerTask(TaskQueue* queue, Task* task_to_queue)
+ : queue_(queue),
+ task_to_queue_(task_to_queue) {
+ }
+
+ virtual void Run() {
+ queue_->Push(task_to_queue_);
+ }
+
+ private:
+ TaskQueue* queue_;
+ Task* task_to_queue_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskQueuerTask);
+};
+
+} // namespace
+
+TEST(TaskQueueTest, RunNoTasks) {
+ TaskQueue queue;
+ EXPECT_TRUE(queue.IsEmpty());
+
+ queue.Run();
+ EXPECT_TRUE(queue.IsEmpty());
+}
+
+TEST(TaskQueueTest, RunTasks) {
+ TaskQueue queue;
+
+ bool ran_task1 = false;
+ bool deleted_task1 = false;
+ queue.Push(new TrackCallsTask(&ran_task1, &deleted_task1));
+
+ bool ran_task2 = false;
+ bool deleted_task2 = false;
+ queue.Push(new TrackCallsTask(&ran_task2, &deleted_task2));
+
+ queue.Run();
+
+ EXPECT_TRUE(ran_task1);
+ EXPECT_TRUE(deleted_task1);
+ EXPECT_TRUE(ran_task2);
+ EXPECT_TRUE(deleted_task2);
+ EXPECT_TRUE(queue.IsEmpty());
+}
+
+TEST(TaskQueueTest, ClearTasks) {
+ TaskQueue queue;
+
+ bool ran_task1 = false;
+ bool deleted_task1 = false;
+ queue.Push(new TrackCallsTask(&ran_task1, &deleted_task1));
+
+ bool ran_task2 = false;
+ bool deleted_task2 = false;
+ queue.Push(new TrackCallsTask(&ran_task2, &deleted_task2));
+
+ queue.Clear();
+
+ EXPECT_TRUE(queue.IsEmpty());
+
+ queue.Run();
+
+ EXPECT_FALSE(ran_task1);
+ EXPECT_TRUE(deleted_task1);
+ EXPECT_FALSE(ran_task2);
+ EXPECT_TRUE(deleted_task2);
+ EXPECT_TRUE(queue.IsEmpty());
+}
+
+TEST(TaskQueueTest, OneTaskQueuesMore) {
+ TaskQueue main_queue;
+
+ // Build a task which will queue two more when run.
+ scoped_ptr<TaskQueue> nested_queue(new TaskQueue());
+ bool ran_task1 = false;
+ bool deleted_task1 = false;
+ nested_queue->Push(
+ new TaskQueuerTask(&main_queue,
+ new TrackCallsTask(&ran_task1, &deleted_task1)));
+ bool ran_task2 = false;
+ bool deleted_task2 = false;
+ nested_queue->Push(
+ new TaskQueuerTask(&main_queue,
+ new TrackCallsTask(&ran_task2, &deleted_task2)));
+
+ main_queue.Push(nested_queue.release());
+
+ // Run the task which pushes two more tasks.
+ main_queue.Run();
+
+ // None of the pushed tasks shoudl have run yet.
+ EXPECT_FALSE(ran_task1);
+ EXPECT_FALSE(deleted_task1);
+ EXPECT_FALSE(ran_task2);
+ EXPECT_FALSE(deleted_task2);
+ EXPECT_FALSE(main_queue.IsEmpty());
+
+ // Now run the nested tasks.
+ main_queue.Run();
+
+ EXPECT_TRUE(ran_task1);
+ EXPECT_TRUE(deleted_task1);
+ EXPECT_TRUE(ran_task2);
+ EXPECT_TRUE(deleted_task2);
+ EXPECT_TRUE(main_queue.IsEmpty());
+}