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

Differential Revision: https://phabricator.services.mozilla.com/D130590
This commit is contained in:
Randell Jesup 2022-03-28 14:26:12 +00:00
Родитель c6e4c8ed0a
Коммит e82e1d91cc
4 изменённых файлов: 41 добавлений и 30 удалений

Просмотреть файл

@ -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().

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);
};
/**

Просмотреть файл

@ -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