Index: media/midi/task_service.h |
diff --git a/media/midi/task_service.h b/media/midi/task_service.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4e7ea79ef98befd48af816945af3d433f20af80e |
--- /dev/null |
+++ b/media/midi/task_service.h |
@@ -0,0 +1,96 @@ |
+// Copyright 2017 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 MEDIA_MIDI_TASK_SERVICE_H_ |
+#define MEDIA_MIDI_TASK_SERVICE_H_ |
+ |
+#include "base/callback_forward.h" |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/synchronization/lock.h" |
+#include "base/threading/thread.h" |
+#include "base/time/time.h" |
+#include "media/midi/midi_export.h" |
+ |
+namespace midi { |
+ |
+// TaskService manages TaskRunners that can be used in midi and provides |
+// functionalities to ensure thread safety. |
+class MIDI_EXPORT TaskService final { |
+ public: |
+ using RunnerId = size_t; |
+ using InstanceId = int; |
+ |
+ static constexpr RunnerId kDefaultRunnerId = 0; |
+ |
+ TaskService(); |
+ ~TaskService(); |
+ |
+ // Issues an InstanceId internally to post tasks via PostBoundTask() and |
+ // PostDelayedBoundTask() with the InstanceId. Once UnbindInstance() is |
+ // called, tasks posted via these methods with unbind InstanceId won't be |
+ // invoked any more. |
+ // Returns true if call is bound or unbound correctly. Otherwise returns |
+ // false, that happens when the BindInstance() is called twice without |
+ // unbinding the previous instance. |
+ bool BindInstance(); |
+ bool UnbindInstance(); |
+ |
+ // Posts a task to run on a specified TaskRunner. |runner_id| should be |
+ // kDefaultRunnerId or a positive number. If kDefaultRunnerId is specified |
+ // the task runs on the thread on which BindInstance() is called. Other number |
+ // will run the task on a dedicated thread that is bound to the |runner_id|. |
+ void PostStaticTask(RunnerId runner_id, base::OnceClosure task); |
+ |
+ // Posts a task to run on a specified TaskRunner, and ensures that the bound |
+ // instance should not quit UnbindInstance() while a bound task is running. |
+ // See PostStaticTask() for |runner_id|. |
+ void PostBoundTask(RunnerId runner, base::OnceClosure task); |
+ void PostBoundDelayedTask(RunnerId runner_id, |
+ base::OnceClosure task, |
+ base::TimeDelta delay); |
+ |
+ private: |
+ // Returns a SingleThreadTaskRunner reference. Each TaskRunner will be |
+ // constructed on demand. |
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(RunnerId runner_id); |
+ |
+ // Helps to run a posted bound task on TaskRunner safely. |
+ void RunTask(InstanceId instance_id, |
+ RunnerId runner_id, |
+ base::OnceClosure task); |
+ |
+ // Keeps a TaskRunner for the thread that calls BindInstance() to post reply |
+ // tasks. |
+ scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner_; |
yhirano
2017/06/13 09:30:47
[optional] PostReplyTask is gone, so it may be goo
Takashi Toyoshima
2017/06/13 10:06:46
Done.
|
+ |
+ // Holds threads to host SingleThreadTaskRunners. |
+ std::vector<std::unique_ptr<base::Thread>> threads_; |
+ |
+ // Holds lock objects to ensure that tasks run while the instance is bound. |
+ std::vector<std::unique_ptr<base::Lock>> thread_task_locks_; |
+ |
+ // Holds InstanceId for the next bound instance. |
+ InstanceId next_instance_id_; |
+ |
+ // Holds InstanceId for the current bound instance. |
+ InstanceId bound_instance_id_; |
+ |
+ // Protects |next_instance_id_| and |bound_instance_id_|. |
+ base::Lock instance_lock_; |
+ |
+ // Protects all other members. |
+ base::Lock lock_; |
+ |
+ // If multiple locks should be obtained simultaneously, we should acquire them |
+ // in the order below so to avoid deadklocks. |
+ // |instance_lock_| -> |lock_| -> |(one of) thread_task_locks_|. |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TaskService); |
+}; |
+ |
+}; // namespace midi |
+ |
+#endif // MEDIA_MIDI_TASK_SERVICE_H_ |