mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1160064 - Switch mirror/canonical initialization to happen in the constructor. r=jww
The goal here is to hoist all meaningful watcher/mirror/canonical manipulation onto the owner thread. But since that must necessarily happen asynchronously, we need to make sure that canonicals are in a sane state immediately upon creation, since otherwise a mirror from another thread may attempt to connect to a not-yet-initialized canonical.
This commit is contained in:
parent
a927a49fdc
commit
e4d299cfff
@ -596,6 +596,9 @@ bool MediaDecoder::IsInfinite()
|
||||
|
||||
MediaDecoder::MediaDecoder() :
|
||||
mWatchManager(this),
|
||||
mNextFrameStatus(AbstractThread::MainThread(),
|
||||
MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED,
|
||||
"MediaDecoder::mNextFrameStatus (Mirror)"),
|
||||
mDecoderPosition(0),
|
||||
mPlaybackPosition(0),
|
||||
mCurrentTime(0.0),
|
||||
@ -606,6 +609,10 @@ MediaDecoder::MediaDecoder() :
|
||||
mMediaSeekable(true),
|
||||
mSameOriginMedia(false),
|
||||
mReentrantMonitor("media.decoder"),
|
||||
mPlayState(AbstractThread::MainThread(), PLAY_STATE_LOADING,
|
||||
"MediaDecoder::mPlayState (Canonical)"),
|
||||
mNextState(AbstractThread::MainThread(), PLAY_STATE_PAUSED,
|
||||
"MediaDecoder::mNextState (Canonical)"),
|
||||
mIgnoreProgressData(false),
|
||||
mInfiniteStream(false),
|
||||
mOwner(nullptr),
|
||||
@ -628,15 +635,6 @@ MediaDecoder::MediaDecoder() :
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MediaMemoryTracker::AddMediaDecoder(this);
|
||||
|
||||
// Initialize canonicals.
|
||||
mPlayState.Init(AbstractThread::MainThread(), PLAY_STATE_LOADING, "MediaDecoder::mPlayState (Canonical)");
|
||||
mNextState.Init(AbstractThread::MainThread(), PLAY_STATE_PAUSED, "MediaDecoder::mNextState (Canonical)");
|
||||
|
||||
// Initialize mirrors.
|
||||
mNextFrameStatus.Init(AbstractThread::MainThread(), MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED,
|
||||
"MediaDecoder::mNextFrameStatus (Mirror)");
|
||||
|
||||
|
||||
mAudioChannel = AudioChannelService::GetDefaultAudioChannel();
|
||||
|
||||
// Initialize watchers.
|
||||
|
@ -212,6 +212,14 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
mStartTime(-1),
|
||||
mEndTime(-1),
|
||||
mDurationSet(false),
|
||||
mPlayState(mTaskQueue, MediaDecoder::PLAY_STATE_LOADING,
|
||||
"MediaDecoderStateMachine::mPlayState (Mirror)",
|
||||
aDecoder->CanonicalPlayState()),
|
||||
mNextPlayState(mTaskQueue, MediaDecoder::PLAY_STATE_PAUSED,
|
||||
"MediaDecoderStateMachine::mNextPlayState (Mirror)",
|
||||
aDecoder->CanonicalNextPlayState()),
|
||||
mNextFrameStatus(mTaskQueue, MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED,
|
||||
"MediaDecoderStateMachine::mNextFrameStatus (Canonical)"),
|
||||
mFragmentEndTime(-1),
|
||||
mReader(aReader),
|
||||
mCurrentFrameTime(0),
|
||||
@ -251,16 +259,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
MOZ_COUNT_CTOR(MediaDecoderStateMachine);
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
|
||||
// Initialize canonicals.
|
||||
mNextFrameStatus.Init(mTaskQueue, MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED,
|
||||
"MediaDecoderStateMachine::mNextFrameStatus (Canonical)");
|
||||
|
||||
// Initialize mirrors.
|
||||
mPlayState.Init(mTaskQueue, MediaDecoder::PLAY_STATE_LOADING, "MediaDecoderStateMachine::mPlayState (Mirror)",
|
||||
aDecoder->CanonicalPlayState());
|
||||
mNextPlayState.Init(mTaskQueue, MediaDecoder::PLAY_STATE_PAUSED, "MediaDecoderStateMachine::mNextPlayState (Mirror)",
|
||||
aDecoder->CanonicalNextPlayState());
|
||||
|
||||
// Initialize watchers.
|
||||
mWatchManager.Watch(mState, &MediaDecoderStateMachine::UpdateNextFrameStatus);
|
||||
mWatchManager.Watch(mAudioCompleted, &MediaDecoderStateMachine::UpdateNextFrameStatus);
|
||||
|
||||
|
@ -112,8 +112,13 @@ template<typename T>
|
||||
class Canonical
|
||||
{
|
||||
public:
|
||||
Canonical() {}
|
||||
~Canonical() { MOZ_DIAGNOSTIC_ASSERT(mImpl, "Should have initialized me"); }
|
||||
Canonical(AbstractThread* aThread, const T& aInitialValue, const char* aName)
|
||||
{
|
||||
mImpl = new Impl(aThread, aInitialValue, aName);
|
||||
}
|
||||
|
||||
|
||||
~Canonical() {}
|
||||
|
||||
private:
|
||||
class Impl : public AbstractCanonical<T>, public WatchTarget
|
||||
@ -233,11 +238,6 @@ public:
|
||||
|
||||
// NB: Because mirror-initiated disconnection can race with canonical-
|
||||
// initiated disconnection, a canonical should never be reinitialized.
|
||||
void Init(AbstractThread* aThread, const T& aInitialValue, const char* aName)
|
||||
{
|
||||
mImpl = new Impl(aThread, aInitialValue, aName);
|
||||
}
|
||||
|
||||
// Forward control operations to the Impl.
|
||||
void DisconnectAll() { return mImpl->DisconnectAll(); }
|
||||
|
||||
@ -272,10 +272,14 @@ template<typename T>
|
||||
class Mirror
|
||||
{
|
||||
public:
|
||||
Mirror() {}
|
||||
Mirror(AbstractThread* aThread, const T& aInitialValue, const char* aName,
|
||||
AbstractCanonical<T>* aCanonical = nullptr)
|
||||
{
|
||||
mImpl = new Impl(aThread, aInitialValue, aName, aCanonical);
|
||||
}
|
||||
|
||||
~Mirror()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(mImpl, "Should have initialized me");
|
||||
if (mImpl->OwnerThread()->IsCurrentThreadIn()) {
|
||||
mImpl->DisconnectIfConnected();
|
||||
} else {
|
||||
@ -371,14 +375,6 @@ private:
|
||||
};
|
||||
public:
|
||||
|
||||
// NB: Because mirror-initiated disconnection can race with canonical-
|
||||
// initiated disconnection, a mirror should never be reinitialized.
|
||||
void Init(AbstractThread* aThread, const T& aInitialValue, const char* aName,
|
||||
AbstractCanonical<T>* aCanonical = nullptr)
|
||||
{
|
||||
mImpl = new Impl(aThread, aInitialValue, aName, aCanonical);
|
||||
}
|
||||
|
||||
// Forward control operations to the Impl<T>.
|
||||
void Connect(AbstractCanonical<T>* aCanonical) { mImpl->Connect(aCanonical); }
|
||||
void DisconnectIfConnected() { mImpl->DisconnectIfConnected(); }
|
||||
|
Loading…
Reference in New Issue
Block a user