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..8b22980d0d1a344637981b5ada8098332020a0e3 |
--- /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 = int; |
+ using InstanceId = int; |
+ |
+ 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. |
+ bool BindInstance(); |
+ bool UnbindInstance(); |
+ |
+ // Posts a task to run on a specified TaskRunner. |
+ void PostStaticTask(RunnerId runner, const base::Closure& task); |
yhirano
2017/06/07 09:21:03
I think OnceClosure and BindOnce are generally pre
Takashi Toyoshima
2017/06/07 13:00:07
Done.
|
+ |
+ // Post a task to run on a specificed TaskRunner, and ensures that the bound |
+ // instance should not quit UnbindInstance() while a bound task is running. |
+ void PostBoundTask(RunnerId runner, const base::Closure& task); |
+ void PostBoundDelayedTask(RunnerId runner, |
+ const base::Closure& task, |
+ base::TimeDelta delay); |
+ |
+ // Posts a task to run on a thread that called BindInstance(), and ensures |
+ // that the bound instance should not quit UnbindInstance() while thee task is |
+ // running. |
+ void PostBoundReplyTask(const base::Closure& task); |
+ |
+ private: |
+ // Returns a SingleThreadTaskRunner reference. Each TaskRunner will be |
+ // constructed on demand. |
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(RunnerId id); |
+ |
+ // Helps to run a posted bound task on TaskRunner safely. |
+ void RunTask(InstanceId instance_id, |
+ RunnerId runner, |
+ const base::Closure& task); |
+ |
+ // Keeps a TaskRunner for the thread that calls BindInstance() to post reply |
+ // tasks. |
+ scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner_; |
+ |
+ // 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 a lock object to ensure that a reply task runs while the instance is |
+ // bound. |
+ base::Lock reply_task_lock_; |
+ |
+ // 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_ |