Bug 1193838 - Make ProfileGatherer exist during the lifetime of a GeckoSampler. r=BenWa

--HG--
extra : commitid : GutYRbuADgV
extra : rebase_source : dc291977bb7ef43a024e26c83abb47b75a82b841
This commit is contained in:
Mike Conley 2015-12-01 13:01:27 -05:00
parent cb4e1a83eb
commit 0069816212
4 changed files with 63 additions and 26 deletions

View File

@ -247,6 +247,8 @@ GeckoSampler::GeckoSampler(double aInterval, int aEntrySize,
mozilla::tasktracer::StartLogging();
}
#endif
mGatherer = new mozilla::ProfileGatherer(this);
}
GeckoSampler::~GeckoSampler()
@ -279,6 +281,10 @@ GeckoSampler::~GeckoSampler()
#if defined(XP_WIN)
delete mIntelPowerGadget;
#endif
// Cancel any in-flight async profile gatherering
// requests
mGatherer->Cancel();
}
void GeckoSampler::HandleSaveRequest()
@ -416,17 +422,11 @@ UniquePtr<char[]> GeckoSampler::ToJSON(double aSinceTime)
void GeckoSampler::ToJSObjectAsync(double aSinceTime,
mozilla::dom::Promise* aPromise)
{
if (NS_WARN_IF(mGatherer)) {
if (NS_WARN_IF(!mGatherer)) {
return;
}
mGatherer = new mozilla::ProfileGatherer(this, aSinceTime, aPromise);
mGatherer->Start();
}
void GeckoSampler::ProfileGathered()
{
mGatherer = nullptr;
mGatherer->Start(aSinceTime, aPromise);
}
struct SubprocessClosure {

View File

@ -127,8 +127,6 @@ class GeckoSampler: public Sampler {
void GetBufferInfo(uint32_t *aCurrentPosition, uint32_t *aTotalSize, uint32_t *aGeneration);
void ProfileGathered();
protected:
// Called within a signal. This function must be reentrant
virtual void InplaceTick(TickSample* sample);

View File

@ -14,13 +14,11 @@ namespace mozilla {
NS_IMPL_ISUPPORTS0(ProfileGatherer)
ProfileGatherer::ProfileGatherer(GeckoSampler* aTicker,
double aSinceTime,
Promise* aPromise)
: mPromise(aPromise)
, mTicker(aTicker)
, mSinceTime(aSinceTime)
ProfileGatherer::ProfileGatherer(GeckoSampler* aTicker)
: mTicker(aTicker)
, mSinceTime(0)
, mPendingProfiles(0)
, mGathering(false)
{
}
@ -50,9 +48,23 @@ ProfileGatherer::WillGatherOOPProfile()
}
void
ProfileGatherer::Start()
ProfileGatherer::Start(double aSinceTime,
Promise* aPromise)
{
MOZ_ASSERT(NS_IsMainThread());
if (mGathering) {
// If we're already gathering, reject the promise - this isn't going
// to end well.
if (aPromise) {
aPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
}
return;
}
mSinceTime = aSinceTime;
mPromise = aPromise;
mGathering = true;
mPendingProfiles = 0;
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os) {
@ -69,15 +81,19 @@ void
ProfileGatherer::Finish()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mTicker) {
// We somehow got called after we were cancelled! This shouldn't
// be possible, but doing a belt-and-suspenders check to be sure.
return;
}
UniquePtr<char[]> buf = mTicker->ToJSON(mSinceTime);
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(mPromise->GlobalJSObject()))) {
// We're really hosed if we can't get a JS context for some reason.
// We'll tell the GeckoSampler that we've gathered the profile just
// so that it can drop the reference to this ProfileGatherer and maybe
// the user can try again.
mTicker->ProfileGathered();
Reset();
return;
}
@ -104,7 +120,29 @@ ProfileGatherer::Finish()
}
}
mTicker->ProfileGathered();
Reset();
}
void
ProfileGatherer::Reset()
{
mSinceTime = 0;
mPromise = nullptr;
mPendingProfiles = 0;
mGathering = false;
}
void
ProfileGatherer::Cancel()
{
// The GeckoSampler is going away. If we have a Promise in flight, we
// should reject it.
if (mPromise) {
mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
// Clear out the GeckoSampler reference, since it's being destroyed.
mTicker = nullptr;
}
} // namespace mozilla

View File

@ -16,21 +16,22 @@ class ProfileGatherer final : public nsISupports
public:
NS_DECL_ISUPPORTS
ProfileGatherer(GeckoSampler* aTicker,
double aSinceTime,
mozilla::dom::Promise* aPromise);
explicit ProfileGatherer(GeckoSampler* aTicker);
void WillGatherOOPProfile();
void GatheredOOPProfile();
void Start();
void Start(double aSinceTime, mozilla::dom::Promise* aPromise);
void Cancel();
private:
~ProfileGatherer() {};
void Finish();
void Reset();
RefPtr<mozilla::dom::Promise> mPromise;
GeckoSampler* mTicker;
double mSinceTime;
uint32_t mPendingProfiles;
bool mGathering;
};
} // namespace mozilla