Chromium Code Reviews| 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..b32944be56b02cdaf6e277f1d4959e3b68221b1e |
| --- /dev/null |
| +++ b/media/midi/task_service.h |
| @@ -0,0 +1,94 @@ |
| +// 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(); |
|
yhirano
2017/06/08 09:03:38
In https://codereview.chromium.org/2923163003/ the
Takashi Toyoshima
2017/06/08 10:30:11
Yeah, I should fix caller side to check this retur
|
| + bool UnbindInstance(); |
| + |
| + // Posts a task to run on a specified TaskRunner. |
| + void PostStaticTask(RunnerId runner, base::OnceClosure task); |
| + |
| + // Post a task to run on a specificed TaskRunner, and ensures that the bound |
|
yhirano
2017/06/08 09:03:38
Post"s"
Takashi Toyoshima
2017/06/08 10:30:11
Done.
|
| + // instance should not quit UnbindInstance() while a bound task is running. |
| + void PostBoundTask(RunnerId runner, base::OnceClosure task); |
|
yhirano
2017/06/08 09:03:38
You should add a comment (and DCHECK) that |runner
Takashi Toyoshima
2017/06/08 10:30:11
That would make code a little confusing due to "in
|
| + void PostBoundDelayedTask(RunnerId runner, |
| + base::OnceClosure 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 |
|
yhirano
2017/06/08 09:03:38
s/thee/the/
Takashi Toyoshima
2017/06/08 10:30:11
Done.
|
| + // running. |
| + void PostBoundReplyTask(base::OnceClosure 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, base::OnceClosure 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_ |