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 #include "media/base/state_machine_driver.h" |
| 6 |
| 7 #include "base/auto_reset.h" |
| 8 #include "base/bind.h" |
| 9 #include "base/threading/thread_task_runner_handle.h" |
| 10 |
| 11 namespace media { |
| 12 |
| 13 StateMachineDriver::StateMachineDriver() |
| 14 : currently_running_(false), |
| 15 run_posted_(false), |
| 16 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 17 weak_factory_(this) {} |
| 18 |
| 19 StateMachineDriver::~StateMachineDriver() {} |
| 20 |
| 21 void StateMachineDriver::RequestRun(StateMachine* machine) { |
| 22 // Note that we might, technically, have this machine in |to_run|, which |
| 23 // would be good enough. as it is, this may schedule a run after that one, |
| 24 // which is also okay. |
| 25 machines_to_run_.insert(machine); |
| 26 |
| 27 // If we're currently running, then RunAfterPost will notice these machines. |
| 28 // Otherwise, post RunAfterPost if we haven't already. |
| 29 if (!currently_running_ && !run_posted_) { |
| 30 task_runner_->PostTask(FROM_HERE, base::Bind(&StateMachineDriver::RunTask, |
| 31 weak_factory_.GetWeakPtr())); |
| 32 |
| 33 // I suppose that we could RequestRun directly here too, since it's not |
| 34 // going to be re-entrant. i'm not sure. if two machines are run by |
| 35 // different drivers, then they might be interleaved, but it's unclear |
| 36 // if that's okay or not. probably, it doesn't matter, since i'd expect |
| 37 // every MCVD to have one driver for all its machines, and the state |
| 38 // wouldn't be shared with other MCVD instances. then again, maybe |
| 39 // codec allocator state would be shared, or similar. in that case, |
| 40 // we might have threading issues to worry about too, if the MCVDs |
| 41 // don't share a common thread. |
| 42 // It's also not clear if we want RequestRun to ever run things before |
| 43 // returning, separately from all of that. We might want two variants: |
| 44 // one that may run immediately, and one that must not. the former |
| 45 // would be useful for polling media codec, where it would be called |
| 46 // from a timer. |
| 47 run_posted_ = true; |
| 48 } |
| 49 } |
| 50 |
| 51 void StateMachineDriver::RunImmediately(StateMachine* machine) { |
| 52 DCHECK(!currently_running_); |
| 53 |
| 54 // TODO(liberato): should we cancel any pending post? It doesn't hurt if |
| 55 // we don't, but we could. |
| 56 machines_to_run_.insert(machine); |
| 57 RunTask(); |
| 58 } |
| 59 |
| 60 void StateMachineDriver::AddStateMachine( |
| 61 std::unique_ptr<StateMachine> machine) { |
| 62 machines_.insert(std::move(machine)); |
| 63 machine->SetOwner(this); |
| 64 } |
| 65 |
| 66 void StateMachineDriver::RunTask() { |
| 67 run_posted_ = false; |
| 68 base::AutoReset<bool> auto_reset(¤tly_running_, true); |
| 69 |
| 70 do { |
| 71 std::unordered_set<StateMachine*> to_run(std::move(machines_to_run_)); |
| 72 for (StateMachine* machine : to_run) |
| 73 machine->Run(); |
| 74 // That might cause more machines to want to run, so keep trying if we |
| 75 // want to. We can choose to post, too, if we want. |
| 76 } while (!machines_to_run_.empty()); |
| 77 } |
| 78 |
| 79 } // namespace media |
OLD | NEW |