Bug 1425458 - Resource timing entries Workers - part 3 - PerformanceStorageWorker, r=smaug
This commit is contained in:
@@ -438,6 +438,7 @@ Performance::InsertResourceEntry(PerformanceEntry* aEntry)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't add the entry if the buffer is full
|
||||||
if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
|
if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,11 +100,15 @@ public:
|
|||||||
|
|
||||||
virtual nsITimedChannel* GetChannel() const = 0;
|
virtual nsITimedChannel* GetChannel() const = 0;
|
||||||
|
|
||||||
|
virtual TimeStamp CreationTimeStamp() const = 0;
|
||||||
|
|
||||||
void MemoryPressure();
|
void MemoryPressure();
|
||||||
|
|
||||||
size_t SizeOfUserEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
|
size_t SizeOfUserEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||||
size_t SizeOfResourceEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
|
size_t SizeOfResourceEntries(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||||
|
|
||||||
|
void InsertResourceEntry(PerformanceEntry* aEntry);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Performance();
|
Performance();
|
||||||
explicit Performance(nsPIDOMWindowInner* aWindow);
|
explicit Performance(nsPIDOMWindowInner* aWindow);
|
||||||
@@ -112,7 +116,6 @@ protected:
|
|||||||
virtual ~Performance();
|
virtual ~Performance();
|
||||||
|
|
||||||
virtual void InsertUserEntry(PerformanceEntry* aEntry);
|
virtual void InsertUserEntry(PerformanceEntry* aEntry);
|
||||||
void InsertResourceEntry(PerformanceEntry* aEntry);
|
|
||||||
|
|
||||||
void ClearUserEntries(const Optional<nsAString>& aEntryName,
|
void ClearUserEntries(const Optional<nsAString>& aEntryName,
|
||||||
const nsAString& aEntryType);
|
const nsAString& aEntryType);
|
||||||
@@ -122,8 +125,6 @@ protected:
|
|||||||
|
|
||||||
virtual void DispatchBufferFullEvent() = 0;
|
virtual void DispatchBufferFullEvent() = 0;
|
||||||
|
|
||||||
virtual TimeStamp CreationTimeStamp() const = 0;
|
|
||||||
|
|
||||||
virtual DOMHighResTimeStamp CreationTime() const = 0;
|
virtual DOMHighResTimeStamp CreationTime() const = 0;
|
||||||
|
|
||||||
virtual bool IsPerformanceTimingAttribute(const nsAString& aName)
|
virtual bool IsPerformanceTimingAttribute(const nsAString& aName)
|
||||||
@@ -137,11 +138,6 @@ protected:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsResourceEntryLimitReached() const
|
|
||||||
{
|
|
||||||
return mResourceEntries.Length() >= mResourceTimingBufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const;
|
void LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const;
|
||||||
void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner,
|
void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner,
|
||||||
uint64_t epoch);
|
uint64_t epoch);
|
||||||
|
|||||||
@@ -118,64 +118,24 @@ PerformanceMainThread::AddEntry(nsIHttpChannel* channel,
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
// Check if resource timing is prefed off.
|
nsAutoString initiatorType;
|
||||||
if (!nsContentUtils::IsResourceTimingEnabled()) {
|
nsAutoString entryName;
|
||||||
|
|
||||||
|
UniquePtr<PerformanceTimingData> performanceTimingData(
|
||||||
|
PerformanceTimingData::Create(timedChannel, channel, 0, initiatorType,
|
||||||
|
entryName));
|
||||||
|
if (!performanceTimingData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't add the entry if the buffer is full
|
// The PerformanceResourceTiming object will use the PerformanceTimingData
|
||||||
if (IsResourceEntryLimitReached()) {
|
// object to get all the required timings.
|
||||||
return;
|
RefPtr<PerformanceResourceTiming> performanceEntry =
|
||||||
}
|
new PerformanceResourceTiming(Move(performanceTimingData), this,
|
||||||
|
entryName);
|
||||||
|
|
||||||
if (channel && timedChannel) {
|
performanceEntry->SetInitiatorType(initiatorType);
|
||||||
nsAutoCString name;
|
InsertResourceEntry(performanceEntry);
|
||||||
nsAutoString initiatorType;
|
|
||||||
nsCOMPtr<nsIURI> originalURI;
|
|
||||||
|
|
||||||
timedChannel->GetInitiatorType(initiatorType);
|
|
||||||
|
|
||||||
// According to the spec, "The name attribute must return the resolved URL
|
|
||||||
// of the requested resource. This attribute must not change even if the
|
|
||||||
// fetch redirected to a different URL."
|
|
||||||
channel->GetOriginalURI(getter_AddRefs(originalURI));
|
|
||||||
originalURI->GetSpec(name);
|
|
||||||
NS_ConvertUTF8toUTF16 entryName(name);
|
|
||||||
|
|
||||||
bool reportTiming = true;
|
|
||||||
timedChannel->GetReportResourceTiming(&reportTiming);
|
|
||||||
|
|
||||||
if (!reportTiming) {
|
|
||||||
#ifdef DEBUG_jwatt
|
|
||||||
NS_WARNING(
|
|
||||||
nsPrintfCString("Not reporting CORS resource: %s", name.get()).get());
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The nsITimedChannel argument will be used to gather all the timings.
|
|
||||||
// The nsIHttpChannel argument will be used to check if any cross-origin
|
|
||||||
// redirects occurred.
|
|
||||||
// The last argument is the "zero time" (offset). Since we don't want
|
|
||||||
// any offset for the resource timing, this will be set to "0" - the
|
|
||||||
// resource timing returns a relative timing (no offset).
|
|
||||||
UniquePtr<PerformanceTimingData> performanceTimingData(
|
|
||||||
new PerformanceTimingData(timedChannel, channel, 0));
|
|
||||||
|
|
||||||
// The PerformanceResourceTiming object will use the PerformanceTiming
|
|
||||||
// object to get all the required timings.
|
|
||||||
RefPtr<PerformanceResourceTiming> performanceEntry =
|
|
||||||
new PerformanceResourceTiming(Move(performanceTimingData), this,
|
|
||||||
entryName);
|
|
||||||
|
|
||||||
// If the initiator type had no valid value, then set it to the default
|
|
||||||
// ("other") value.
|
|
||||||
if (initiatorType.IsEmpty()) {
|
|
||||||
initiatorType = NS_LITERAL_STRING("other");
|
|
||||||
}
|
|
||||||
performanceEntry->SetInitiatorType(initiatorType);
|
|
||||||
InsertResourceEntry(performanceEntry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// To be removed once bug 1124165 lands
|
// To be removed once bug 1124165 lands
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ class nsITimedChannel;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class PerformanceTimingData;
|
||||||
|
|
||||||
class PerformanceStorage
|
class PerformanceStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -23,7 +25,6 @@ public:
|
|||||||
virtual void AddEntry(nsIHttpChannel* aChannel,
|
virtual void AddEntry(nsIHttpChannel* aChannel,
|
||||||
nsITimedChannel* aTimedChannel) = 0;
|
nsITimedChannel* aTimedChannel) = 0;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~PerformanceStorage() {}
|
virtual ~PerformanceStorage() {}
|
||||||
};
|
};
|
||||||
|
|||||||
271
dom/performance/PerformanceStorageWorker.cpp
Normal file
271
dom/performance/PerformanceStorageWorker.cpp
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "PerformanceStorageWorker.h"
|
||||||
|
#include "WorkerPrivate.h"
|
||||||
|
#include "WorkerHolder.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
using namespace workers;
|
||||||
|
|
||||||
|
class PerformanceProxyData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PerformanceProxyData(UniquePtr<PerformanceTimingData>&& aData,
|
||||||
|
const nsAString& aInitiatorType,
|
||||||
|
const nsAString& aEntryName)
|
||||||
|
: mData(Move(aData))
|
||||||
|
, mInitiatorType(aInitiatorType)
|
||||||
|
, mEntryName(aEntryName)
|
||||||
|
{}
|
||||||
|
|
||||||
|
UniquePtr<PerformanceTimingData> mData;
|
||||||
|
nsString mInitiatorType;
|
||||||
|
nsString mEntryName;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// This runnable calls InitializeOnWorker() on the worker thread. Here a
|
||||||
|
// workerHolder is used to monitor when the worker thread is starting the
|
||||||
|
// shutdown procedure.
|
||||||
|
// Here we use control runnable because this code must be executed also when in
|
||||||
|
// a sync event loop.
|
||||||
|
class PerformanceStorageInitializer final : public WorkerControlRunnable
|
||||||
|
{
|
||||||
|
RefPtr<PerformanceStorageWorker> mStorage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PerformanceStorageInitializer(WorkerPrivate* aWorkerPrivate,
|
||||||
|
PerformanceStorageWorker* aStorage)
|
||||||
|
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
|
||||||
|
, mStorage(aStorage)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||||
|
{
|
||||||
|
mStorage->InitializeOnWorker();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Cancel() override
|
||||||
|
{
|
||||||
|
mStorage->ShutdownOnWorker();
|
||||||
|
return WorkerRunnable::Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PreDispatch(WorkerPrivate* aWorkerPrivate) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Here we use control runnable because this code must be executed also when in
|
||||||
|
// a sync event loop
|
||||||
|
class PerformanceEntryAdder final : public WorkerControlRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PerformanceEntryAdder(WorkerPrivate* aWorkerPrivate,
|
||||||
|
PerformanceStorageWorker* aStorage,
|
||||||
|
UniquePtr<PerformanceProxyData>&& aData)
|
||||||
|
: WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
|
||||||
|
, mStorage(aStorage)
|
||||||
|
, mData(Move(aData))
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
|
||||||
|
{
|
||||||
|
mStorage->AddEntryOnWorker(Move(mData));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Cancel() override
|
||||||
|
{
|
||||||
|
mStorage->ShutdownOnWorker();
|
||||||
|
return WorkerRunnable::Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PreDispatch(WorkerPrivate* aWorkerPrivate) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PostDispatch(WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefPtr<PerformanceStorageWorker> mStorage;
|
||||||
|
UniquePtr<PerformanceProxyData> mData;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PerformanceStorageWorkerHolder final : public WorkerHolder
|
||||||
|
{
|
||||||
|
RefPtr<PerformanceStorageWorker> mStorage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PerformanceStorageWorkerHolder(PerformanceStorageWorker* aStorage)
|
||||||
|
: WorkerHolder("PerformanceStorageWorkerHolder",
|
||||||
|
WorkerHolder::AllowIdleShutdownStart)
|
||||||
|
, mStorage(aStorage)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Notify(Status aStatus) override
|
||||||
|
{
|
||||||
|
if (mStorage) {
|
||||||
|
RefPtr<PerformanceStorageWorker> storage;
|
||||||
|
storage.swap(mStorage);
|
||||||
|
storage->ShutdownOnWorker();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous
|
||||||
|
|
||||||
|
/* static */ already_AddRefed<PerformanceStorageWorker>
|
||||||
|
PerformanceStorageWorker::Create(WorkerPrivate* aWorkerPrivate)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
RefPtr<PerformanceStorageWorker> storage =
|
||||||
|
new PerformanceStorageWorker(aWorkerPrivate);
|
||||||
|
|
||||||
|
RefPtr<PerformanceStorageInitializer> r =
|
||||||
|
new PerformanceStorageInitializer(aWorkerPrivate, storage);
|
||||||
|
if (NS_WARN_IF(!r->Dispatch())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return storage.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceStorageWorker::PerformanceStorageWorker(WorkerPrivate* aWorkerPrivate)
|
||||||
|
: mMutex("PerformanceStorageWorker::mMutex")
|
||||||
|
, mWorkerPrivate(aWorkerPrivate)
|
||||||
|
, mState(eInitializing)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceStorageWorker::~PerformanceStorageWorker() = default;
|
||||||
|
|
||||||
|
void
|
||||||
|
PerformanceStorageWorker::AddEntry(nsIHttpChannel* aChannel,
|
||||||
|
nsITimedChannel* aTimedChannel)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
|
if (mState == eTerminated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString initiatorType;
|
||||||
|
nsAutoString entryName;
|
||||||
|
|
||||||
|
UniquePtr<PerformanceTimingData> performanceTimingData(
|
||||||
|
PerformanceTimingData::Create(aTimedChannel, aChannel, 0, initiatorType,
|
||||||
|
entryName));
|
||||||
|
if (!performanceTimingData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UniquePtr<PerformanceProxyData> data(
|
||||||
|
new PerformanceProxyData(Move(performanceTimingData), initiatorType,
|
||||||
|
entryName));
|
||||||
|
|
||||||
|
RefPtr<PerformanceEntryAdder> r =
|
||||||
|
new PerformanceEntryAdder(mWorkerPrivate, this, Move(data));
|
||||||
|
Unused << NS_WARN_IF(!r->Dispatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PerformanceStorageWorker::InitializeOnWorker()
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
MOZ_ASSERT(mState == eInitializing);
|
||||||
|
MOZ_ASSERT(mWorkerPrivate);
|
||||||
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
|
mWorkerHolder.reset(new PerformanceStorageWorkerHolder(this));
|
||||||
|
if (!mWorkerHolder->HoldWorker(mWorkerPrivate, Canceling)) {
|
||||||
|
MutexAutoUnlock lock(mMutex);
|
||||||
|
ShutdownOnWorker();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are ready to accept entries.
|
||||||
|
mState = eReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PerformanceStorageWorker::ShutdownOnWorker()
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
|
if (mState == eTerminated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(mWorkerPrivate);
|
||||||
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
|
mState = eTerminated;
|
||||||
|
mWorkerHolder = nullptr;
|
||||||
|
mWorkerPrivate = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PerformanceStorageWorker::AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData)
|
||||||
|
{
|
||||||
|
RefPtr<Performance> performance;
|
||||||
|
UniquePtr<PerformanceProxyData> data = Move(aData);
|
||||||
|
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
|
||||||
|
if (mState == eTerminated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(mWorkerPrivate);
|
||||||
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
|
MOZ_ASSERT(mState == eReady);
|
||||||
|
|
||||||
|
WorkerGlobalScope* scope = mWorkerPrivate->GlobalScope();
|
||||||
|
performance = scope->GetPerformance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!performance)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<PerformanceResourceTiming> performanceEntry =
|
||||||
|
new PerformanceResourceTiming(Move(data->mData), performance,
|
||||||
|
data->mEntryName);
|
||||||
|
performanceEntry->SetInitiatorType(data->mInitiatorType);
|
||||||
|
|
||||||
|
performance->InsertResourceEntry(performanceEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
64
dom/performance/PerformanceStorageWorker.h
Normal file
64
dom/performance/PerformanceStorageWorker.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_PerformanceStorageWorker_h
|
||||||
|
#define mozilla_dom_PerformanceStorageWorker_h
|
||||||
|
|
||||||
|
#include "PerformanceStorage.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
namespace workers {
|
||||||
|
class WorkerHolder;
|
||||||
|
class WorkerPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PerformanceProxyData;
|
||||||
|
|
||||||
|
class PerformanceStorageWorker final : public PerformanceStorage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PerformanceStorageWorker, override)
|
||||||
|
|
||||||
|
static already_AddRefed<PerformanceStorageWorker>
|
||||||
|
Create(workers::WorkerPrivate* aWorkerPrivate);
|
||||||
|
|
||||||
|
void InitializeOnWorker();
|
||||||
|
|
||||||
|
void ShutdownOnWorker();
|
||||||
|
|
||||||
|
void AddEntry(nsIHttpChannel* aChannel,
|
||||||
|
nsITimedChannel* aTimedChannel) override;
|
||||||
|
|
||||||
|
void AddEntryOnWorker(UniquePtr<PerformanceProxyData>&& aData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit PerformanceStorageWorker(workers::WorkerPrivate* aWorkerPrivate);
|
||||||
|
~PerformanceStorageWorker();
|
||||||
|
|
||||||
|
Mutex mMutex;
|
||||||
|
|
||||||
|
// Protected by mutex.
|
||||||
|
// This raw pointer is nullified when the WorkerHolder communicates the
|
||||||
|
// shutting down of the worker thread.
|
||||||
|
workers::WorkerPrivate* mWorkerPrivate;
|
||||||
|
|
||||||
|
// Protected by mutex.
|
||||||
|
enum {
|
||||||
|
eInitializing,
|
||||||
|
eReady,
|
||||||
|
eTerminated,
|
||||||
|
} mState;
|
||||||
|
|
||||||
|
// Touched on worker-thread only.
|
||||||
|
UniquePtr<WorkerHolder> mWorkerHolder;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_PerformanceStorageWorker_h
|
||||||
@@ -20,6 +20,58 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceTiming, mPerformance)
|
|||||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceTiming, AddRef)
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceTiming, AddRef)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
|
||||||
|
|
||||||
|
/* static */ PerformanceTimingData*
|
||||||
|
PerformanceTimingData::Create(nsITimedChannel* aTimedChannel,
|
||||||
|
nsIHttpChannel* aChannel,
|
||||||
|
DOMHighResTimeStamp aZeroTime,
|
||||||
|
nsAString& aInitiatorType,
|
||||||
|
nsAString& aEntryName)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
// Check if resource timing is prefed off.
|
||||||
|
if (!nsContentUtils::IsResourceTimingEnabled()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aChannel || !aTimedChannel) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool reportTiming = true;
|
||||||
|
aTimedChannel->GetReportResourceTiming(&reportTiming);
|
||||||
|
|
||||||
|
if (!reportTiming) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
aTimedChannel->GetInitiatorType(aInitiatorType);
|
||||||
|
|
||||||
|
// If the initiator type had no valid value, then set it to the default
|
||||||
|
// ("other") value.
|
||||||
|
if (aInitiatorType.IsEmpty()) {
|
||||||
|
aInitiatorType = NS_LITERAL_STRING("other");
|
||||||
|
}
|
||||||
|
|
||||||
|
// According to the spec, "The name attribute must return the resolved URL
|
||||||
|
// of the requested resource. This attribute must not change even if the
|
||||||
|
// fetch redirected to a different URL."
|
||||||
|
nsCOMPtr<nsIURI> originalURI;
|
||||||
|
aChannel->GetOriginalURI(getter_AddRefs(originalURI));
|
||||||
|
|
||||||
|
nsAutoCString name;
|
||||||
|
originalURI->GetSpec(name);
|
||||||
|
aEntryName = NS_ConvertUTF8toUTF16(name);
|
||||||
|
|
||||||
|
// The nsITimedChannel argument will be used to gather all the timings.
|
||||||
|
// The nsIHttpChannel argument will be used to check if any cross-origin
|
||||||
|
// redirects occurred.
|
||||||
|
// The last argument is the "zero time" (offset). Since we don't want
|
||||||
|
// any offset for the resource timing, this will be set to "0" - the
|
||||||
|
// resource timing returns a relative timing (no offset).
|
||||||
|
return new PerformanceTimingData(aTimedChannel, aChannel, 0);
|
||||||
|
}
|
||||||
|
|
||||||
PerformanceTiming::PerformanceTiming(Performance* aPerformance,
|
PerformanceTiming::PerformanceTiming(Performance* aPerformance,
|
||||||
nsITimedChannel* aChannel,
|
nsITimedChannel* aChannel,
|
||||||
nsIHttpChannel* aHttpChannel,
|
nsIHttpChannel* aHttpChannel,
|
||||||
|
|||||||
@@ -20,9 +20,21 @@ class nsITimedChannel;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class PerformanceTiming;
|
||||||
|
|
||||||
class PerformanceTimingData final
|
class PerformanceTimingData final
|
||||||
{
|
{
|
||||||
|
friend class PerformanceTiming;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// This can return null.
|
||||||
|
static PerformanceTimingData*
|
||||||
|
Create(nsITimedChannel* aChannel,
|
||||||
|
nsIHttpChannel* aHttpChannel,
|
||||||
|
DOMHighResTimeStamp aZeroTime,
|
||||||
|
nsAString& aInitiatorType,
|
||||||
|
nsAString& aEntryName);
|
||||||
|
|
||||||
PerformanceTimingData(nsITimedChannel* aChannel,
|
PerformanceTimingData(nsITimedChannel* aChannel,
|
||||||
nsIHttpChannel* aHttpChannel,
|
nsIHttpChannel* aHttpChannel,
|
||||||
DOMHighResTimeStamp aZeroTime);
|
DOMHighResTimeStamp aZeroTime);
|
||||||
@@ -109,8 +121,7 @@ public:
|
|||||||
MOZ_ASSERT(aPerformance);
|
MOZ_ASSERT(aPerformance);
|
||||||
MOZ_ASSERT(!aStamp.IsNull());
|
MOZ_ASSERT(!aStamp.IsNull());
|
||||||
|
|
||||||
TimeDuration duration =
|
TimeDuration duration = aStamp - aPerformance->CreationTimeStamp();
|
||||||
aStamp - aPerformance->GetDOMTiming()->GetNavigationStartTimeStamp();
|
|
||||||
return duration.ToMilliseconds() + mZeroTime;
|
return duration.ToMilliseconds() + mZeroTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ EXPORTS.mozilla.dom += [
|
|||||||
'PerformanceResourceTiming.h',
|
'PerformanceResourceTiming.h',
|
||||||
'PerformanceService.h',
|
'PerformanceService.h',
|
||||||
'PerformanceStorage.h',
|
'PerformanceStorage.h',
|
||||||
|
'PerformanceStorageWorker.h',
|
||||||
'PerformanceTiming.h',
|
'PerformanceTiming.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ UNIFIED_SOURCES += [
|
|||||||
'PerformanceObserverEntryList.cpp',
|
'PerformanceObserverEntryList.cpp',
|
||||||
'PerformanceResourceTiming.cpp',
|
'PerformanceResourceTiming.cpp',
|
||||||
'PerformanceService.cpp',
|
'PerformanceService.cpp',
|
||||||
|
'PerformanceStorageWorker.cpp',
|
||||||
'PerformanceTiming.cpp',
|
'PerformanceTiming.cpp',
|
||||||
'PerformanceWorker.cpp',
|
'PerformanceWorker.cpp',
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
#include "mozilla/dom/MessagePortBinding.h"
|
#include "mozilla/dom/MessagePortBinding.h"
|
||||||
#include "mozilla/dom/nsCSPUtils.h"
|
#include "mozilla/dom/nsCSPUtils.h"
|
||||||
#include "mozilla/dom/Performance.h"
|
#include "mozilla/dom/Performance.h"
|
||||||
|
#include "mozilla/dom/PerformanceStorageWorker.h"
|
||||||
#include "mozilla/dom/PMessagePort.h"
|
#include "mozilla/dom/PMessagePort.h"
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
#include "mozilla/dom/PromiseDebugging.h"
|
#include "mozilla/dom/PromiseDebugging.h"
|
||||||
@@ -7203,8 +7204,12 @@ PerformanceStorage*
|
|||||||
WorkerPrivate::GetPerformanceStorage()
|
WorkerPrivate::GetPerformanceStorage()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
// TODO
|
|
||||||
return nullptr;
|
if (!mPerformanceStorage) {
|
||||||
|
mPerformanceStorage = PerformanceStorageWorker::Create(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mPerformanceStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(ExternalRunnableWrapper, WorkerRunnable)
|
NS_IMPL_ISUPPORTS_INHERITED0(ExternalRunnableWrapper, WorkerRunnable)
|
||||||
|
|||||||
@@ -1068,6 +1068,8 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
|||||||
// fired on the main thread if the worker script fails to load
|
// fired on the main thread if the worker script fails to load
|
||||||
nsCOMPtr<nsIRunnable> mLoadFailedRunnable;
|
nsCOMPtr<nsIRunnable> mLoadFailedRunnable;
|
||||||
|
|
||||||
|
RefPtr<PerformanceStorage> mPerformanceStorage;
|
||||||
|
|
||||||
JS::UniqueChars mDefaultLocale; // nulled during worker JSContext init
|
JS::UniqueChars mDefaultLocale; // nulled during worker JSContext init
|
||||||
TimeStamp mKillTime;
|
TimeStamp mKillTime;
|
||||||
uint32_t mErrorHandlerRecursionCount;
|
uint32_t mErrorHandlerRecursionCount;
|
||||||
|
|||||||
Reference in New Issue
Block a user