Index: cc/base/blocking_task_runner.h |
diff --git a/cc/base/blocking_task_runner.h b/cc/base/blocking_task_runner.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f74e21f5b73d4cccc601d3fa2eb04ac70dfd97d3 |
--- /dev/null |
+++ b/cc/base/blocking_task_runner.h |
@@ -0,0 +1,97 @@ |
+// Copyright 2013 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 CC_BASE_BLOCKING_TASK_RUNNER_H_ |
+#define CC_BASE_BLOCKING_TASK_RUNNER_H_ |
+ |
+#include <vector> |
+ |
+#include "base/location.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/synchronization/lock.h" |
+#include "base/threading/platform_thread.h" |
+ |
+namespace cc { |
+ |
+// This class wraps a SingleThreadTaskRunner but allows posted tasks to be |
+// run without a round trip through the message loop. This shortcutting |
+// removes guarantees about ordering. Tasks posted while the |
+// BlockingTaskRunner is in a capturing state will run in order, and tasks |
+// posted while the BlockingTaskRunner is /not/ in a capturing state will |
+// run in order, but the two sets of tasks will *not* run in order relative |
+// to when they were posted. |
+// |
+// To use this class, post tasks to the task runner returned by |
+// BlockingTaskRunner::Create(). The thread it is created on identifies the |
+// thread you want the tasks to run on. The SingleThreadTaskRunner which is |
+// passed into Create() is used to run tasks that are posted when not in a |
+// capturing state. |
+// |
+// Then, on the thread that the given task runner belongs to, you may |
+// instantiate a BlockingTaskRunner::CapturePostTasks. While this object |
+// exists, the task runner will collect any PostTasks called on it, posting |
+// tasks to that thread from anywhere. This CapturePostTasks object provides |
+// a window in time where tasks can shortcut past the MessageLoop. As soon |
+// as the CapturePostTasks object is destroyed (goes out of scope), all |
+// tasks that had been posted to the thread during the window will be executed |
+// immediately. |
+// |
+// Beware of re-entrancy, make sure the CapturePostTasks object is destroyed at |
+// a time when it makes sense for the embedder to call arbitrary things. |
+class BlockingTaskRunner { |
+ public: |
+ // Creates a BlockingTaskRunner for a given SingleThreadTaskRunner. |
+ // |task_runner| will be used to run the tasks which are posted while we are |
+ // not capturing. |task_runner| should belong to same the thread on which |
+ // capturing is done. |
+ static scoped_ptr<BlockingTaskRunner> Create( |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ |
+ ~BlockingTaskRunner(); |
+ |
+ // While an object of this type is held alive on a thread, any tasks |
+ // posted to the thread will be captured and run as soon as the object |
+ // is destroyed, shortcutting past the task runner. |
+ class CapturePostTasks { |
+ public: |
+ explicit CapturePostTasks(BlockingTaskRunner* blocking_runner); |
+ ~CapturePostTasks(); |
+ |
+ private: |
+ BlockingTaskRunner* blocking_runner_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CapturePostTasks); |
+ }; |
+ |
+ // True if tasks posted to the BlockingTaskRunner will run on the current |
+ // thread. |
+ bool BelongsToCurrentThread(); |
+ |
+ // Posts a task using the contained SingleThreadTaskRunner unless |capture_| |
+ // is true. When |capture_| is true, tasks posted will be caught and stored |
+ // until the capturing stops. At that time the tasks will be run directly |
+ // instead of being posted to the SingleThreadTaskRunner. |
+ bool PostTask(const tracked_objects::Location& from_here, |
+ const base::Closure& task); |
+ |
+ private: |
+ explicit BlockingTaskRunner( |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ |
+ void SetCapture(bool capture); |
+ |
+ base::PlatformThreadId thread_id_; |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ |
+ base::Lock lock_; |
+ int capture_; |
+ std::vector<base::Closure> captured_tasks_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BlockingTaskRunner); |
+}; |
+ |
+} // namespace cc |
+ |
+#endif // CC_BASE_BLOCKING_TASK_RUNNER_H_ |