OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef MEDIA_BASE_STATE_MACHINE_DRIVER_H_ |
| 6 #define MEDIA_BASE_STATE_MACHINE_DRIVER_H_ |
| 7 |
| 8 #include <unordered_set> |
| 9 |
| 10 #include "base/memory/ref_counted.h" |
| 11 #include "base/memory/weak_ptr.h" |
| 12 #include "base/single_thread_task_runner.h" |
| 13 #include "media/base/media_export.h" |
| 14 #include "media/base/state_machine.h" |
| 15 |
| 16 namespace media { |
| 17 |
| 18 // Drives one or more state machines. |
| 19 // Drivers own machines. machines own (shared) state. all machines in a driver |
| 20 // are run on a single thread. if state is shared between machines on different |
| 21 // drivers that also are on different threads, then i'm not sure. i guess that |
| 22 // the state would have to know (task_runner, client) for each client and post |
| 23 // if it's on the wrong one. plus, it would have to implement locking for its |
| 24 // getters and setters. plus, it's unclear if state when state is allowed to |
| 25 // change -- can it switch during a run of a machine? |
| 26 // Also note that the driver doesn't need to own a new thread. |
| 27 // For right now, it's better to think about everything on one thread. |
| 28 class MEDIA_EXPORT StateMachineDriver : public StateMachine::Owner { |
| 29 public: |
| 30 StateMachineDriver(); |
| 31 virtual ~StateMachineDriver(); |
| 32 |
| 33 public: |
| 34 // Makes sure that |machine| will run, but not re-entrantly. Multiple calls |
| 35 // to this before it starts running are the same as one call. If |machine| is |
| 36 // currently running, or of some machine that this driver owns is running, |
| 37 // then it will not be run |machine| until later. |
| 38 // Note that it's unclear if this may run |machine| before it returns if no |
| 39 // machine that we own is running. If there are two variants, maybe only |
| 40 // one is part of the owner interface. We might expose a different call |
| 41 // that allows / requires |machine| to be run before it returns, |
| 42 // specifically to support cases like polling media codec. |
| 43 void RequestRun(StateMachine* machine) override; |
| 44 |
| 45 // Run |machine| immediately, before returning. |
| 46 // We might want a 'request run immediately before returning' that can be |
| 47 // used by something that's definitely not re-entrant, such as the timer |
| 48 // task that polls media codec. That timer task could be started / stopped |
| 49 // by state (e.g. 'last useful work time'), but that state would just have |
| 50 // some side-effects. Another example might be AVDA::Decode, or anything |
| 51 // else that calls DoIOTask() now. |
| 52 // Note that this does not guarantee that only |machine| will run, nor that |
| 53 // |machine| will run first. If you want that guarantee, then it's likely |
| 54 // that your state machine needs to be revised a bit. |
| 55 // TODO(liberato): should we just have 'RequestRun' and 'RunPendingMachines'? |
| 56 // We could, but RequestRun will try to post a task, since it doesn't know |
| 57 // that it should also run immediately. the post won't hurt, but it's a |
| 58 // waste of effort to do so. |
| 59 void RunImmediately(StateMachine* machine); |
| 60 |
| 61 // maybe NotifyMachinePending() to add to the running set, then RequestRun() |
| 62 // to run them at a steady state (post), or RunImmediately() to run them |
| 63 // before the call returns. that would let one add multiple machines to |
| 64 // the set before running them immediately, though i suppose one could call |
| 65 // RunImmediately multiple times. |
| 66 |
| 67 // Adds |machine| to our set of owned machines. We will run this when it |
| 68 // requests it, along with other machines. |
| 69 void AddStateMachine(std::unique_ptr<StateMachine> machine); |
| 70 |
| 71 protected: |
| 72 // Run by the posted task. Will run all machine in |machines_to_run_|, |
| 73 // and maybe more if that causes more to become ready. |
| 74 void RunTask(); |
| 75 |
| 76 private: |
| 77 // All the machines we own. |
| 78 std::unordered_set<std::unique_ptr<StateMachine>> machines_; |
| 79 |
| 80 // Set of machines that would like to run. Set by RequestRun. Must be a |
| 81 // subset of |machines_|. |
| 82 std::unordered_set<StateMachine*> machines_to_run_; |
| 83 |
| 84 // Set / cleared by RunAfterPost to indicate that RunAfterPost is running. |
| 85 bool currently_running_; |
| 86 |
| 87 // Set when a post to start the machine is pending. Cleared by RunAfterPost |
| 88 // when it runs. |
| 89 bool run_posted_; |
| 90 |
| 91 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 92 |
| 93 base::WeakPtrFactory<StateMachineDriver> weak_factory_; |
| 94 |
| 95 DISALLOW_COPY_AND_ASSIGN(StateMachineDriver); |
| 96 }; |
| 97 |
| 98 } // namespace media |
| 99 |
| 100 #endif // MEDIA_BASE_STATE_MACHINE_DRIVER_H_ |
OLD | NEW |