diff options
author | levin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 06:09:38 +0000 |
---|---|---|
committer | levin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 06:09:38 +0000 |
commit | 6fd0ca52fbb5d33e3355c0ebe8fe81219be90de0 (patch) | |
tree | 6a24baf9874440f81fde368ab964ffc0d912c2d5 /base | |
parent | b924ae04055aa82cd19ef522b690e3cd66352c11 (diff) | |
download | chromium_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.gyp | 1 | ||||
-rw-r--r-- | base/base.gypi | 2 | ||||
-rw-r--r-- | base/task_queue.cc | 49 | ||||
-rw-r--r-- | base/task_queue.h | 43 | ||||
-rw-r--r-- | base/task_queue_unittest.cc | 147 |
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()); +} |