forked from mirrors/gecko-dev
Bug 1859200 permit AppendMessage() with other ControlMessageInterface objects r=pehrsons
A similar assertion will be added to new methods for other ControlMessageInterface objects in a subsequent patch. MediaTrackGraphImpl::OpenAudioInput() and AudioListener::SendListenerEngineEvent() are two of a number of cases that construct a ControlMessage with a null track. Differential Revision: https://phabricator.services.mozilla.com/D191061
This commit is contained in:
parent
ce078b9839
commit
8a25ccdeef
4 changed files with 28 additions and 23 deletions
|
|
@ -1284,7 +1284,7 @@ void MediaTrackGraphImpl::ProduceDataForTracksBlockByBlock(
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaTrackGraphImpl::RunMessageAfterProcessing(
|
void MediaTrackGraphImpl::RunMessageAfterProcessing(
|
||||||
UniquePtr<ControlMessage> aMessage) {
|
UniquePtr<ControlMessageInterface> aMessage) {
|
||||||
MOZ_ASSERT(OnGraphThread());
|
MOZ_ASSERT(OnGraphThread());
|
||||||
|
|
||||||
if (mFrontMessageQueue.IsEmpty()) {
|
if (mFrontMessageQueue.IsEmpty()) {
|
||||||
|
|
@ -1303,7 +1303,7 @@ void MediaTrackGraphImpl::RunMessagesInQueue() {
|
||||||
// batch corresponding to an event loop task). This isolates the performance
|
// batch corresponding to an event loop task). This isolates the performance
|
||||||
// of different scripts to some extent.
|
// of different scripts to some extent.
|
||||||
for (uint32_t i = 0; i < mFrontMessageQueue.Length(); ++i) {
|
for (uint32_t i = 0; i < mFrontMessageQueue.Length(); ++i) {
|
||||||
nsTArray<UniquePtr<ControlMessage>>& messages =
|
nsTArray<UniquePtr<ControlMessageInterface>>& messages =
|
||||||
mFrontMessageQueue[i].mMessages;
|
mFrontMessageQueue[i].mMessages;
|
||||||
|
|
||||||
for (uint32_t j = 0; j < messages.Length(); ++j) {
|
for (uint32_t j = 0; j < messages.Length(); ++j) {
|
||||||
|
|
@ -1868,7 +1868,8 @@ void MediaTrackGraphImpl::RunInStableState(bool aSourceIsMTG) {
|
||||||
// When we're doing a forced shutdown, pending control messages may be
|
// When we're doing a forced shutdown, pending control messages may be
|
||||||
// run on the main thread via RunDuringShutdown. Those messages must
|
// run on the main thread via RunDuringShutdown. Those messages must
|
||||||
// run without the graph monitor being held. So, we collect them here.
|
// run without the graph monitor being held. So, we collect them here.
|
||||||
nsTArray<UniquePtr<ControlMessage>> controlMessagesToRunDuringShutdown;
|
nsTArray<UniquePtr<ControlMessageInterface>>
|
||||||
|
controlMessagesToRunDuringShutdown;
|
||||||
|
|
||||||
{
|
{
|
||||||
MonitorAutoLock lock(mMonitor);
|
MonitorAutoLock lock(mMonitor);
|
||||||
|
|
@ -2031,10 +2032,9 @@ void MediaTrackGraphImpl::SignalMainThreadCleanup() {
|
||||||
EnsureStableStateEventPosted();
|
EnsureStableStateEventPosted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaTrackGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage) {
|
void MediaTrackGraphImpl::AppendMessage(
|
||||||
|
UniquePtr<ControlMessageInterface> aMessage) {
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "main thread only");
|
MOZ_ASSERT(NS_IsMainThread(), "main thread only");
|
||||||
MOZ_RELEASE_ASSERT(!aMessage->GetTrack() ||
|
|
||||||
!aMessage->GetTrack()->IsDestroyed());
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mMainThreadTrackCount > 0 || mMainThreadPortCount > 0);
|
MOZ_DIAGNOSTIC_ASSERT(mMainThreadTrackCount > 0 || mMainThreadPortCount > 0);
|
||||||
|
|
||||||
if (!mGraphDriverRunning &&
|
if (!mGraphDriverRunning &&
|
||||||
|
|
|
||||||
|
|
@ -72,12 +72,14 @@ struct TrackUpdate {
|
||||||
* This represents a message run on the graph thread to modify track or graph
|
* This represents a message run on the graph thread to modify track or graph
|
||||||
* state. These are passed from main thread to graph thread through
|
* state. These are passed from main thread to graph thread through
|
||||||
* AppendMessage(), or scheduled on the graph thread with
|
* AppendMessage(), or scheduled on the graph thread with
|
||||||
* RunMessageAfterProcessing(). A ControlMessage
|
* RunMessageAfterProcessing(). A ControlMessage often has
|
||||||
* always has a weak reference to a particular affected track.
|
* a weak reference to a particular affected track.
|
||||||
*/
|
*/
|
||||||
class ControlMessage : public MediaTrack::ControlMessageInterface {
|
class ControlMessage : public MediaTrack::ControlMessageInterface {
|
||||||
public:
|
public:
|
||||||
explicit ControlMessage(MediaTrack* aTrack) : mTrack(aTrack) {}
|
explicit ControlMessage(MediaTrack* aTrack) : mTrack(aTrack) {
|
||||||
|
MOZ_RELEASE_ASSERT(!aTrack || !NS_IsMainThread() || !aTrack->IsDestroyed());
|
||||||
|
}
|
||||||
|
|
||||||
MediaTrack* GetTrack() { return mTrack; }
|
MediaTrack* GetTrack() { return mTrack; }
|
||||||
|
|
||||||
|
|
@ -90,7 +92,7 @@ class ControlMessage : public MediaTrack::ControlMessageInterface {
|
||||||
|
|
||||||
class MessageBlock {
|
class MessageBlock {
|
||||||
public:
|
public:
|
||||||
nsTArray<UniquePtr<ControlMessage>> mMessages;
|
nsTArray<UniquePtr<MediaTrack::ControlMessageInterface>> mMessages;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -180,10 +182,10 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
||||||
*/
|
*/
|
||||||
void ApplyTrackUpdate(TrackUpdate* aUpdate) MOZ_REQUIRES(mMonitor);
|
void ApplyTrackUpdate(TrackUpdate* aUpdate) MOZ_REQUIRES(mMonitor);
|
||||||
/**
|
/**
|
||||||
* Append a ControlMessage to the message queue. This queue is drained
|
* Append a control message to the message queue. This queue is drained
|
||||||
* during RunInStableState; the messages will run on the graph thread.
|
* during RunInStableState; the messages will run on the graph thread.
|
||||||
*/
|
*/
|
||||||
virtual void AppendMessage(UniquePtr<ControlMessage> aMessage);
|
virtual void AppendMessage(UniquePtr<ControlMessageInterface> aMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches a runnable from any thread to the correct main thread for this
|
* Dispatches a runnable from any thread to the correct main thread for this
|
||||||
|
|
@ -330,7 +332,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
||||||
* Schedules |aMessage| to run after processing, at a time when graph state
|
* Schedules |aMessage| to run after processing, at a time when graph state
|
||||||
* can be changed. Graph thread.
|
* can be changed. Graph thread.
|
||||||
*/
|
*/
|
||||||
void RunMessageAfterProcessing(UniquePtr<ControlMessage> aMessage);
|
void RunMessageAfterProcessing(UniquePtr<ControlMessageInterface> aMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the GraphStartedPromise when the driver has started processing on
|
* Resolve the GraphStartedPromise when the driver has started processing on
|
||||||
|
|
@ -664,7 +666,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
||||||
* Main-thread view of the number of ports in this graph, to catch bugs.
|
* Main-thread view of the number of ports in this graph, to catch bugs.
|
||||||
*
|
*
|
||||||
* When this becomes zero, and mMainThreadTrackCount is 0, the graph is
|
* When this becomes zero, and mMainThreadTrackCount is 0, the graph is
|
||||||
* marked as forbidden to add more ControlMessages to. It will be shut down
|
* marked as forbidden to add more control messages to. It will be shut down
|
||||||
* shortly after.
|
* shortly after.
|
||||||
*/
|
*/
|
||||||
size_t mMainThreadPortCount = 0;
|
size_t mMainThreadPortCount = 0;
|
||||||
|
|
@ -772,7 +774,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
||||||
// MediaTrackGraph normally does its work without holding mMonitor, so it is
|
// MediaTrackGraph normally does its work without holding mMonitor, so it is
|
||||||
// not safe to just grab mMonitor from some thread and start monkeying with
|
// not safe to just grab mMonitor from some thread and start monkeying with
|
||||||
// the graph. Instead, communicate with the graph thread using provided
|
// the graph. Instead, communicate with the graph thread using provided
|
||||||
// mechanisms such as the ControlMessage queue.
|
// mechanisms such as the control message queue.
|
||||||
Monitor mMonitor;
|
Monitor mMonitor;
|
||||||
|
|
||||||
// Data guarded by mMonitor (must always be accessed with mMonitor held,
|
// Data guarded by mMonitor (must always be accessed with mMonitor held,
|
||||||
|
|
@ -925,7 +927,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
||||||
* immediately because we want all messages between stable states to be
|
* immediately because we want all messages between stable states to be
|
||||||
* processed as an atomic batch.
|
* processed as an atomic batch.
|
||||||
*/
|
*/
|
||||||
nsTArray<UniquePtr<ControlMessage>> mCurrentTaskMessageQueue;
|
nsTArray<UniquePtr<ControlMessageInterface>> mCurrentTaskMessageQueue;
|
||||||
/**
|
/**
|
||||||
* True from when RunInStableState sets mLifecycleState to LIFECYCLE_RUNNING,
|
* True from when RunInStableState sets mLifecycleState to LIFECYCLE_RUNNING,
|
||||||
* until RunInStableState has determined that mLifecycleState is >
|
* until RunInStableState has determined that mLifecycleState is >
|
||||||
|
|
@ -995,7 +997,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/**
|
/**
|
||||||
* Used to assert when AppendMessage() runs ControlMessages synchronously.
|
* Used to assert when AppendMessage() runs control messages synchronously.
|
||||||
*/
|
*/
|
||||||
bool mCanRunMessagesSynchronously;
|
bool mCanRunMessagesSynchronously;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ using namespace mozilla::media;
|
||||||
using testing::AssertionResult;
|
using testing::AssertionResult;
|
||||||
using testing::NiceMock;
|
using testing::NiceMock;
|
||||||
using testing::Return;
|
using testing::Return;
|
||||||
|
using ControlMessageInterface = MediaTrack::ControlMessageInterface;
|
||||||
|
|
||||||
constexpr uint32_t kNoFlags = 0;
|
constexpr uint32_t kNoFlags = 0;
|
||||||
constexpr TrackRate kRate = 44100;
|
constexpr TrackRate kRate = 44100;
|
||||||
|
|
@ -40,7 +41,7 @@ class MockTestGraph : public MediaTrackGraphImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_CONST_METHOD0(OnGraphThread, bool());
|
MOCK_CONST_METHOD0(OnGraphThread, bool());
|
||||||
MOCK_METHOD1(AppendMessage, void(UniquePtr<ControlMessage>));
|
MOCK_METHOD1(AppendMessage, void(UniquePtr<ControlMessageInterface>));
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~MockTestGraph() = default;
|
~MockTestGraph() = default;
|
||||||
|
|
@ -320,8 +321,9 @@ TEST_F(TestAudioDecoderInputTrack, VolumeChange) {
|
||||||
// one for setting the track's volume, another for the track destruction.
|
// one for setting the track's volume, another for the track destruction.
|
||||||
EXPECT_CALL(*mGraph, AppendMessage)
|
EXPECT_CALL(*mGraph, AppendMessage)
|
||||||
.Times(2)
|
.Times(2)
|
||||||
.WillOnce([](UniquePtr<ControlMessage> aMessage) { aMessage->Run(); })
|
.WillOnce(
|
||||||
.WillOnce([](UniquePtr<ControlMessage> aMessage) {});
|
[](UniquePtr<ControlMessageInterface> aMessage) { aMessage->Run(); })
|
||||||
|
.WillOnce([](UniquePtr<ControlMessageInterface> aMessage) {});
|
||||||
|
|
||||||
// The default volume is 1.0.
|
// The default volume is 1.0.
|
||||||
float expectedVolume = 1.0;
|
float expectedVolume = 1.0;
|
||||||
|
|
@ -419,8 +421,9 @@ TEST_F(TestAudioDecoderInputTrack, PlaybackRateChange) {
|
||||||
// one for setting the track's playback, another for the track destruction.
|
// one for setting the track's playback, another for the track destruction.
|
||||||
EXPECT_CALL(*mGraph, AppendMessage)
|
EXPECT_CALL(*mGraph, AppendMessage)
|
||||||
.Times(2)
|
.Times(2)
|
||||||
.WillOnce([](UniquePtr<ControlMessage> aMessage) { aMessage->Run(); })
|
.WillOnce(
|
||||||
.WillOnce([](UniquePtr<ControlMessage> aMessage) {});
|
[](UniquePtr<ControlMessageInterface> aMessage) { aMessage->Run(); })
|
||||||
|
.WillOnce([](UniquePtr<ControlMessageInterface> aMessage) {});
|
||||||
|
|
||||||
// Changing the playback rate.
|
// Changing the playback rate.
|
||||||
float expectedPlaybackRate = 2.0;
|
float expectedPlaybackRate = 2.0;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ class MockGraphImpl : public MediaTrackGraphImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_CONST_METHOD0(OnGraphThread, bool());
|
MOCK_CONST_METHOD0(OnGraphThread, bool());
|
||||||
MOCK_METHOD1(AppendMessage, void(UniquePtr<ControlMessage>));
|
MOCK_METHOD1(AppendMessage, void(UniquePtr<ControlMessageInterface>));
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~MockGraphImpl() = default;
|
~MockGraphImpl() = default;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue