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 "GraphDriver.h" 11 #include "MediaSegment.h" 12 #include "mozilla/Monitor.h" 13 14 #include <thread> 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, GraphTime aIterationEnd, 39 AudioMixer* aMixer); 40 41 /** 42 * Runs mGraph until it shuts down. 43 */ 44 NS_IMETHOD Run(); 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 GraphTime mIterationEnd; 67 AudioMixer* MOZ_NON_OWNING_REF mMixer; 68 69 public: IterationState(GraphTime aStateTime,GraphTime aIterationEnd,AudioMixer * aMixer)70 IterationState(GraphTime aStateTime, GraphTime aIterationEnd, 71 AudioMixer* aMixer) 72 : mStateTime(aStateTime), 73 mIterationEnd(aIterationEnd), 74 mMixer(aMixer) {} 75 IterationState& operator=(const IterationState& aOther) = default; StateTime()76 GraphTime StateTime() const { return mStateTime; } IterationEnd()77 GraphTime IterationEnd() const { return mIterationEnd; } Mixer()78 AudioMixer* Mixer() const { return mMixer; } 79 }; 80 81 // Monitor used for yielding mThread through Wait(), and scheduling mThread 82 // through Signal() from a GraphDriver. 83 Monitor mMonitor; 84 // The MediaTrackGraph we're running. Weakptr beecause this graph owns us and 85 // guarantees that our lifetime will not go beyond that of itself. 86 MediaTrackGraphImpl* const mGraph; 87 // State being handed over to the graph through OneIteration. Protected by 88 // mMonitor. 89 Maybe<IterationState> mIterationState; 90 // Result from mGraph's OneIteration. Protected by mMonitor. 91 IterationResult mIterationResult; 92 93 enum class ThreadState { 94 Wait, // Waiting for a message. This is the initial state. 95 // A transition from Run back to Wait occurs on the runner thread 96 // after it processes as far as mIterationState->mStateTime 97 // and sets mIterationResult. 98 Run, // Set on driver thread after each mIterationState update. 99 Shutdown, // Set when Shutdown() is called on main thread. 100 }; 101 // Protected by mMonitor until set to Shutdown, after which this is not 102 // modified. 103 ThreadState mThreadState; 104 105 // The thread running mGraph. Set on construction, after other members are 106 // initialized. Cleared at the end of Shutdown(). 107 const nsCOMPtr<nsIThread> mThread; 108 109 #ifdef DEBUG 110 // Set to mGraph's audio callback driver's thread id, if run by an 111 // AudioCallbackDriver, while OneIteration() is running. 112 std::thread::id mAudioDriverThreadId = std::thread::id(); 113 // Set to mGraph's system clock driver's thread, if run by a 114 // SystemClockDriver, while OneIteration() is running. 115 nsIThread* mClockDriverThread = nullptr; 116 #endif 117 }; 118 119 } // namespace mozilla 120 121 #endif 122