GraphRunner.h (3879B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_GraphRunner_h 8 #define mozilla_GraphRunner_h 9 10 #include <thread> 11 12 #include "GraphDriver.h" 13 #include "MediaSegment.h" 14 #include "mozilla/Monitor.h" 15 16 struct PRThread; 17 18 namespace mozilla { 19 20 class AudioMixer; 21 class MediaTrackGraphImpl; 22 23 class GraphRunner final : public Runnable { 24 using IterationResult = GraphInterface::IterationResult; 25 26 public: 27 static already_AddRefed<GraphRunner> Create(MediaTrackGraphImpl* aGraph); 28 29 /** 30 * Marks us as shut down and signals mThread, so that it runs until the end. 31 */ 32 MOZ_CAN_RUN_SCRIPT void Shutdown(); 33 34 /** 35 * Signals one iteration of mGraph. Hands state over to mThread and runs 36 * the iteration there. 37 */ 38 IterationResult OneIteration(GraphTime aStateTime, 39 MixerCallbackReceiver* aMixerReceiver); 40 41 /** 42 * Runs mGraph until it shuts down. 43 */ 44 NS_IMETHOD Run() override; 45 46 /** 47 * Returns true if called on mThread. 48 */ 49 bool OnThread() const; 50 51 #ifdef DEBUG 52 /** 53 * Returns true if called on mThread, and aDriver was the driver that called 54 * OneIteration() last. 55 */ 56 bool InDriverIteration(const GraphDriver* aDriver) const; 57 #endif 58 59 private: 60 explicit GraphRunner(MediaTrackGraphImpl* aGraph, 61 already_AddRefed<nsIThread> aThread); 62 ~GraphRunner(); 63 64 class IterationState { 65 GraphTime mStateTime; 66 MixerCallbackReceiver* MOZ_NON_OWNING_REF mMixerReceiver; 67 68 public: 69 IterationState(GraphTime aStateTime, MixerCallbackReceiver* aMixerReceiver) 70 : mStateTime(aStateTime), mMixerReceiver(aMixerReceiver) {} 71 IterationState& operator=(const IterationState& aOther) = default; 72 GraphTime StateTime() const { return mStateTime; } 73 MixerCallbackReceiver* MixerReceiver() const { return mMixerReceiver; } 74 }; 75 76 // Monitor used for yielding mThread through Wait(), and scheduling mThread 77 // through Signal() from a GraphDriver. 78 Monitor mMonitor; 79 // The MediaTrackGraph we're running. Weakptr beecause this graph owns us and 80 // guarantees that our lifetime will not go beyond that of itself. 81 MediaTrackGraphImpl* const mGraph; 82 // State being handed over to the graph through OneIteration. Protected by 83 // mMonitor. 84 Maybe<IterationState> mIterationState MOZ_GUARDED_BY(mMonitor); 85 // Result from mGraph's OneIteration. Protected by mMonitor. 86 IterationResult mIterationResult MOZ_GUARDED_BY(mMonitor); 87 88 enum class ThreadState { 89 Wait, // Waiting for a message. This is the initial state. 90 // A transition from Run back to Wait occurs on the runner thread 91 // after it processes as far as mIterationState->mStateTime 92 // and sets mIterationResult. 93 Run, // Set on driver thread after each mIterationState update. 94 Shutdown, // Set when Shutdown() is called on main thread. 95 }; 96 // Protected by mMonitor until set to Shutdown, after which this is not 97 // modified. 98 ThreadState mThreadState MOZ_GUARDED_BY(mMonitor); 99 100 // The thread running mGraph. Set on construction, after other members are 101 // initialized. Cleared at the end of Shutdown(). 102 const nsCOMPtr<nsIThread> mThread; 103 104 #ifdef DEBUG 105 // Set to mGraph's audio callback driver's thread id, if run by an 106 // AudioCallbackDriver, while OneIteration() is running. 107 std::thread::id mAudioDriverThreadId = std::thread::id(); 108 // Set to mGraph's system clock driver's thread, if run by a 109 // SystemClockDriver, while OneIteration() is running. 110 nsIThread* mClockDriverThread = nullptr; 111 #endif 112 }; 113 114 } // namespace mozilla 115 116 #endif