Commit e82e1d91 authored by Randell Jesup's avatar Randell Jesup
Browse files

Bug 1207753 - MediaTrackGraph* thread-safety annotations r=padenot

parent c6e4c8ed
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -80,15 +80,15 @@ class GraphRunner final : public Runnable {

  // Monitor used for yielding mThread through Wait(), and scheduling mThread
  // through Signal() from a GraphDriver.
  Monitor mMonitor MOZ_UNANNOTATED;
  Monitor mMonitor;
  // The MediaTrackGraph we're running. Weakptr beecause this graph owns us and
  // guarantees that our lifetime will not go beyond that of itself.
  MediaTrackGraphImpl* const mGraph;
  // State being handed over to the graph through OneIteration. Protected by
  // mMonitor.
  Maybe<IterationState> mIterationState;
  Maybe<IterationState> mIterationState GUARDED_BY(mMonitor);
  // Result from mGraph's OneIteration. Protected by mMonitor.
  IterationResult mIterationResult;
  IterationResult mIterationResult GUARDED_BY(mMonitor);

  enum class ThreadState {
    Wait,      // Waiting for a message.  This is the initial state.
@@ -100,7 +100,7 @@ class GraphRunner final : public Runnable {
  };
  // Protected by mMonitor until set to Shutdown, after which this is not
  // modified.
  ThreadState mThreadState;
  ThreadState mThreadState GUARDED_BY(mMonitor);

  // The thread running mGraph.  Set on construction, after other members are
  // initialized.  Cleared at the end of Shutdown().
+11 −1
Original line number Diff line number Diff line
@@ -1382,7 +1382,16 @@ auto MediaTrackGraphImpl::OneIterationImpl(GraphTime aStateTime,
  // thread, and so the monitor need not be held to check mLifecycleState.
  // LIFECYCLE_THREAD_NOT_STARTED is possible when shutting down offline
  // graphs that have not started.

  // While changes occur on mainthread, this assert confirms that
  // this code shouldn't run if mainthread might be changing the state (to
  // > LIFECYCLE_RUNNING)

  // Ignore mutex warning: static during execution of the graph
  PUSH_IGNORE_THREAD_SAFETY
  MOZ_DIAGNOSTIC_ASSERT(mLifecycleState <= LIFECYCLE_RUNNING);
  POP_THREAD_SAFETY

  MOZ_ASSERT(OnGraphThread());

  WebCore::DenormalDisabler disabler;
@@ -2570,7 +2579,8 @@ bool SourceMediaTrack::PullNewData(GraphTime aDesiredUpToTime) {
 */
static void MoveToSegment(SourceMediaTrack* aTrack, MediaSegment* aIn,
                          MediaSegment* aOut, TrackTime aCurrentTime,
                          TrackTime aDesiredUpToTime) {
                          TrackTime aDesiredUpToTime)
    REQUIRES(aTrack->GetMutex()) {
  MOZ_ASSERT(aIn->GetType() == aOut->GetType());
  MOZ_ASSERT(aOut->GetDuration() >= aCurrentTime);
  MOZ_ASSERT(aDesiredUpToTime >= aCurrentTime);
+9 −8
Original line number Diff line number Diff line
@@ -667,9 +667,9 @@ class SourceMediaTrack : public MediaTrack {
  // The value set here is applied in MoveToSegment so we can avoid the
  // buffering delay in applying the change. See Bug 1443511.
  void SetVolume(float aVolume);
  float GetVolumeLocked();
  float GetVolumeLocked() REQUIRES(mMutex);

  Mutex& GetMutex() { return mMutex; }
  Mutex& GetMutex() RETURN_CAPABILITY(mMutex) { return mMutex; }

  friend class MediaTrackGraphImpl;

@@ -702,7 +702,7 @@ class SourceMediaTrack : public MediaTrack {

  bool NeedsMixing();

  void ResampleAudioToGraphSampleRate(MediaSegment* aSegment);
  void ResampleAudioToGraphSampleRate(MediaSegment* aSegment) REQUIRES(mMutex);

  void AddDirectListenerImpl(
      already_AddRefed<DirectMediaTrackListener> aListener) override;
@@ -714,7 +714,7 @@ class SourceMediaTrack : public MediaTrack {
   * from AppendData on the thread providing the data, and will call
   * the Listeners on this thread.
   */
  void NotifyDirectConsumers(MediaSegment* aSegment);
  void NotifyDirectConsumers(MediaSegment* aSegment) REQUIRES(mMutex);

  void OnGraphThreadDone() override {
    MutexAutoLock lock(mMutex);
@@ -733,11 +733,12 @@ class SourceMediaTrack : public MediaTrack {

  // This must be acquired *before* MediaTrackGraphImpl's lock, if they are
  // held together.
  Mutex mMutex MOZ_UNANNOTATED;
  Mutex mMutex;
  // protected by mMutex
  float mVolume = 1.0;
  UniquePtr<TrackData> mUpdateTrack;
  nsTArray<RefPtr<DirectMediaTrackListener>> mDirectTrackListeners;
  float mVolume GUARDED_BY(mMutex) = 1.0;
  UniquePtr<TrackData> mUpdateTrack GUARDED_BY(mMutex);
  nsTArray<RefPtr<DirectMediaTrackListener>> mDirectTrackListeners
      GUARDED_BY(mMutex);
};

/**
+17 −17
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
  /**
   * Called to apply a TrackUpdate to its track.
   */
  void ApplyTrackUpdate(TrackUpdate* aUpdate);
  void ApplyTrackUpdate(TrackUpdate* aUpdate) REQUIRES(mMonitor);
  /**
   * Append a ControlMessage to the message queue. This queue is drained
   * during RunInStableState; the messages will run on the graph thread.
@@ -258,12 +258,12 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   * mMonitor must be held.
   * See EnsureRunInStableState
   */
  void EnsureStableStateEventPosted();
  void EnsureStableStateEventPosted() REQUIRES(mMonitor);
  /**
   * Generate messages to the main thread to update it for all state changes.
   * mMonitor must be held.
   */
  void PrepareUpdatesToMainThreadState(bool aFinalUpdate);
  void PrepareUpdatesToMainThreadState(bool aFinalUpdate) REQUIRES(mMonitor);
  /**
   * If we are rendering in non-realtime mode, we don't want to send messages to
   * the main thread at each iteration for performance reasons. We instead
@@ -297,7 +297,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   */
  void UpdateGraph(GraphTime aEndBlockingDecisions);

  void SwapMessageQueues() {
  void SwapMessageQueues() REQUIRES(mMonitor) {
    MOZ_ASSERT(OnGraphThreadOrNotRunning());
    mMonitor.AssertCurrentThreadOwns();
    MOZ_ASSERT(mFrontMessageQueue.IsEmpty());
@@ -528,7 +528,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
  /**
   * Not safe to call off the MediaTrackGraph thread unless monitor is held!
   */
  GraphDriver* CurrentDriver() const {
  GraphDriver* CurrentDriver() const NO_THREAD_SAFETY_ANALYSIS {
#ifdef DEBUG
    if (!OnGraphThreadOrNotRunning()) {
      mMonitor.AssertCurrentThreadOwns();
@@ -767,7 +767,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
  // not safe to just grab mMonitor from some thread and start monkeying with
  // the graph. Instead, communicate with the graph thread using provided
  // mechanisms such as the ControlMessage queue.
  Monitor mMonitor MOZ_UNANNOTATED;
  Monitor mMonitor;

  // Data guarded by mMonitor (must always be accessed with mMonitor held,
  // regardless of the value of mLifecycleState).
@@ -775,11 +775,11 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
  /**
   * State to copy to main thread
   */
  nsTArray<TrackUpdate> mTrackUpdates;
  nsTArray<TrackUpdate> mTrackUpdates GUARDED_BY(mMonitor);
  /**
   * Runnables to run after the next update to main thread state.
   */
  nsTArray<nsCOMPtr<nsIRunnable>> mUpdateRunnables;
  nsTArray<nsCOMPtr<nsIRunnable>> mUpdateRunnables GUARDED_BY(mMonitor);
  /**
   * A list of batches of messages to process. Each batch is processed
   * as an atomic unit.
@@ -793,10 +793,10 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   * Message queue in which the main thread appends messages.
   * Access guarded by mMonitor.
   */
  nsTArray<MessageBlock> mBackMessageQueue;
  nsTArray<MessageBlock> mBackMessageQueue GUARDED_BY(mMonitor);

  /* True if there will messages to process if we swap the message queues. */
  bool MessagesQueued() const {
  bool MessagesQueued() const REQUIRES(mMonitor) {
    mMonitor.AssertCurrentThreadOwns();
    return !mBackMessageQueue.IsEmpty();
  }
@@ -850,8 +850,8 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   * LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP occur on the graph thread at
   * the end of an iteration.  All other transitions occur on the main thread.
   */
  LifecycleState mLifecycleState;
  LifecycleState& LifecycleStateRef() {
  LifecycleState mLifecycleState GUARDED_BY(mMonitor);
  LifecycleState& LifecycleStateRef() NO_THREAD_SAFETY_ANALYSIS {
#if DEBUG
    if (mGraphDriverRunning) {
      mMonitor.AssertCurrentThreadOwns();
@@ -861,7 +861,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
#endif
    return mLifecycleState;
  }
  const LifecycleState& LifecycleStateRef() const {
  const LifecycleState& LifecycleStateRef() const NO_THREAD_SAFETY_ANALYSIS {
#if DEBUG
    if (mGraphDriverRunning) {
      mMonitor.AssertCurrentThreadOwns();
@@ -887,7 +887,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   * forced) has commenced.  Set on the main thread under mMonitor and read on
   * the graph thread under mMonitor.
   **/
  bool mInterruptJSCalled = false;
  bool mInterruptJSCalled GUARDED_BY(mMonitor) = false;

  /**
   * Remove this blocker to unblock shutdown.
@@ -900,7 +900,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   * RunInStableState() and the event hasn't run yet.
   * Accessed on both main and MTG thread, mMonitor must be held.
   */
  bool mPostedRunInStableStateEvent;
  bool mPostedRunInStableStateEvent GUARDED_BY(mMonitor);

  /**
   * The JSContext of the graph thread.  Set under mMonitor on only the graph
@@ -908,7 +908,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   * the thread is about to exit.  Read under mMonitor on the main thread to
   * interrupt running JS for forced shutdown.
   **/
  JSContext* mJSContext = nullptr;
  JSContext* mJSContext GUARDED_BY(mMonitor) = nullptr;

  // Main thread only

@@ -999,7 +999,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
   * Set based on mProcessedTime at end of iteration.
   * Read by stable state runnable on main thread. Protected by mMonitor.
   */
  GraphTime mNextMainThreadGraphTime = 0;
  GraphTime mNextMainThreadGraphTime GUARDED_BY(mMonitor) = 0;

  /**
   * Cached audio output latency, in seconds. Main thread only. This is reset