Bug 1310086. Part 3 - let SeekingState/ShutdownState::Enter() return a promise. r=kaku

MozReview-Commit-ID: 4TvsISriclT

--HG--
extra : rebase_source : c6557664b974f7cfd12848e152aab0499827b429
extra : source : f91fef194c601a5d63e835d00e69c30cd50a885e
This commit is contained in:
JW Wang 2016-10-13 13:53:32 +08:00
Родитель 8e136dd5e8
Коммит c841d66e5e
1 изменённых файлов: 27 добавлений и 36 удалений

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

@ -233,13 +233,14 @@ public:
// Note this function will delete the current state object. // Note this function will delete the current state object.
// Don't access members to avoid UAF after this call. // Don't access members to avoid UAF after this call.
template <class S, typename... Ts> template <class S, typename... Ts>
void SetState(Ts&&... aArgs) auto SetState(Ts&&... aArgs)
-> decltype(DeclVal<S>().Enter(Forward<Ts>(aArgs)...))
{ {
// keep mMaster in a local object because mMaster will become invalid after // keep mMaster in a local object because mMaster will become invalid after
// the current state object is deleted. // the current state object is deleted.
auto master = mMaster; auto master = mMaster;
auto s = new S(master, Forward<Ts>(aArgs)...); auto s = new S(master);
MOZ_ASSERT(master->mState != s->GetState() || MOZ_ASSERT(master->mState != s->GetState() ||
master->mState == DECODER_STATE_SEEKING); master->mState == DECODER_STATE_SEEKING);
@ -249,7 +250,7 @@ public:
Exit(); Exit();
master->mState = s->GetState(); master->mState = s->GetState();
master->mStateObj.reset(s); // Will delete |this|! master->mStateObj.reset(s); // Will delete |this|!
s->Enter(); return s->Enter(Forward<Ts>(aArgs)...);
} }
protected: protected:
@ -580,11 +581,12 @@ class MediaDecoderStateMachine::SeekingState
: public MediaDecoderStateMachine::StateObject : public MediaDecoderStateMachine::StateObject
{ {
public: public:
explicit SeekingState(Master* aPtr, SeekJob aSeekJob) explicit SeekingState(Master* aPtr) : StateObject(aPtr) {}
: StateObject(aPtr), mSeekJob(Move(aSeekJob)) {}
void Enter() RefPtr<MediaDecoder::SeekPromise> Enter(SeekJob aSeekJob)
{ {
mSeekJob = Move(aSeekJob);
// SeekTask will register its callbacks to MediaDecoderReaderWrapper. // SeekTask will register its callbacks to MediaDecoderReaderWrapper.
mMaster->CancelMediaDecoderReaderWrapperCallback(); mMaster->CancelMediaDecoderReaderWrapperCallback();
@ -640,6 +642,7 @@ public:
})); }));
MOZ_ASSERT(!mMaster->mQueuedSeek.Exists()); MOZ_ASSERT(!mMaster->mQueuedSeek.Exists());
return mSeekJob.mPromise.Ensure(__func__);
} }
void Exit() override void Exit() override
@ -865,7 +868,7 @@ class MediaDecoderStateMachine::ShutdownState
public: public:
explicit ShutdownState(Master* aPtr) : StateObject(aPtr) {} explicit ShutdownState(Master* aPtr) : StateObject(aPtr) {}
void Enter(); RefPtr<ShutdownPromise> Enter();
void Exit() override void Exit() override
{ {
@ -918,14 +921,7 @@ RefPtr<ShutdownPromise>
MediaDecoderStateMachine:: MediaDecoderStateMachine::
StateObject::HandleShutdown() StateObject::HandleShutdown()
{ {
auto master = mMaster; return SetState<ShutdownState>();
SetState<ShutdownState>();
return master->mReader->Shutdown()
->Then(master->OwnerThread(), __func__, master,
&MediaDecoderStateMachine::FinishShutdown,
&MediaDecoderStateMachine::FinishShutdown)
->CompletionPromise();
} }
void void
@ -1074,9 +1070,7 @@ DecodingFirstFrameState::HandleSeek(SeekTarget aTarget)
SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds()); SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
SeekJob seekJob; SeekJob seekJob;
seekJob.mTarget = aTarget; seekJob.mTarget = aTarget;
RefPtr<MediaDecoder::SeekPromise> p = seekJob.mPromise.Ensure(__func__); return SetState<SeekingState>(Move(seekJob));
SetState<SeekingState>(Move(seekJob));
return p.forget();
} }
void void
@ -1131,9 +1125,7 @@ DecodingState::HandleSeek(SeekTarget aTarget)
SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds()); SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
SeekJob seekJob; SeekJob seekJob;
seekJob.mTarget = aTarget; seekJob.mTarget = aTarget;
RefPtr<MediaDecoder::SeekPromise> p = seekJob.mPromise.Ensure(__func__); return SetState<SeekingState>(Move(seekJob));
SetState<SeekingState>(Move(seekJob));
return p.forget();
} }
bool bool
@ -1215,9 +1207,7 @@ SeekingState::HandleSeek(SeekTarget aTarget)
SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds()); SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
SeekJob seekJob; SeekJob seekJob;
seekJob.mTarget = aTarget; seekJob.mTarget = aTarget;
RefPtr<MediaDecoder::SeekPromise> p = seekJob.mPromise.Ensure(__func__); return SetState<SeekingState>(Move(seekJob));
SetState<SeekingState>(Move(seekJob));
return p.forget();
} }
void void
@ -1366,9 +1356,7 @@ BufferingState::HandleSeek(SeekTarget aTarget)
SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds()); SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
SeekJob seekJob; SeekJob seekJob;
seekJob.mTarget = aTarget; seekJob.mTarget = aTarget;
RefPtr<MediaDecoder::SeekPromise> p = seekJob.mPromise.Ensure(__func__); return SetState<SeekingState>(Move(seekJob));
SetState<SeekingState>(Move(seekJob));
return p.forget();
} }
RefPtr<MediaDecoder::SeekPromise> RefPtr<MediaDecoder::SeekPromise>
@ -1379,12 +1367,10 @@ CompletedState::HandleSeek(SeekTarget aTarget)
SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds()); SLOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
SeekJob seekJob; SeekJob seekJob;
seekJob.mTarget = aTarget; seekJob.mTarget = aTarget;
RefPtr<MediaDecoder::SeekPromise> p = seekJob.mPromise.Ensure(__func__); return SetState<SeekingState>(Move(seekJob));
SetState<SeekingState>(Move(seekJob));
return p.forget();
} }
void RefPtr<ShutdownPromise>
MediaDecoderStateMachine:: MediaDecoderStateMachine::
ShutdownState::Enter() ShutdownState::Enter()
{ {
@ -1444,6 +1430,12 @@ ShutdownState::Enter()
// Shut down the watch manager to stop further notifications. // Shut down the watch manager to stop further notifications.
master->mWatchManager.Shutdown(); master->mWatchManager.Shutdown();
return Reader()->Shutdown()
->Then(OwnerThread(), __func__, master,
&MediaDecoderStateMachine::FinishShutdown,
&MediaDecoderStateMachine::FinishShutdown)
->CompletionPromise();
} }
#define INIT_WATCHABLE(name, val) \ #define INIT_WATCHABLE(name, val) \
@ -2309,11 +2301,10 @@ void MediaDecoderStateMachine::VisibilityChanged()
MediaDecoderEventVisibility::Suppressed, MediaDecoderEventVisibility::Suppressed,
true /* aVideoOnly */); true /* aVideoOnly */);
RefPtr<MediaDecoder::SeekPromise> p = seekJob.mPromise.Ensure(__func__); mStateObj->SetState<SeekingState>(Move(seekJob))->Then(
p->Then(AbstractThread::MainThread(), __func__, AbstractThread::MainThread(), __func__,
[start, info, hw](){ ReportRecoveryTelemetry(start, info, hw); }, [start, info, hw](){ ReportRecoveryTelemetry(start, info, hw); },
[](){}); [](){});
mStateObj->SetState<SeekingState>(Move(seekJob));
} }
} }