Bug 1423495 - Part6: Use threadsafe refcounting for nsServerTiming r=baku,nwgh
* Also keeps the timing array as nsTArray<nsCOMPtr<nsIServerTiming>> instead of the scriptable nsIArray (which doesn't like being released on another thread) MozReview-Commit-ID: 37uPZJ38saQ
This commit is contained in:
@@ -98,19 +98,10 @@ PerformanceResourceTiming::GetServerTiming(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIArray> serverTimingArray = mTimingData->GetServerTiming();
|
nsTArray<nsCOMPtr<nsIServerTiming>> serverTimingArray = mTimingData->GetServerTiming();
|
||||||
if (!serverTimingArray) {
|
uint32_t length = serverTimingArray.Length();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t length = 0;
|
|
||||||
if (NS_WARN_IF(NS_FAILED(serverTimingArray->GetLength(&length)))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t index = 0; index < length; ++index) {
|
for (uint32_t index = 0; index < length; ++index) {
|
||||||
nsCOMPtr<nsIServerTiming> serverTiming =
|
nsCOMPtr<nsIServerTiming> serverTiming = serverTimingArray.ElementAt(index);
|
||||||
do_QueryElementAt(serverTimingArray, index);
|
|
||||||
MOZ_ASSERT(serverTiming);
|
MOZ_ASSERT(serverTiming);
|
||||||
|
|
||||||
aRetval.AppendElement(
|
aRetval.AppendElement(
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ PerformanceTimingData::PerformanceTimingData(nsITimedChannel* aChannel,
|
|||||||
// ServiceWorker interception responseStart?
|
// ServiceWorker interception responseStart?
|
||||||
aChannel->GetHandleFetchEventEnd(&mWorkerResponseEnd);
|
aChannel->GetHandleFetchEventEnd(&mWorkerResponseEnd);
|
||||||
|
|
||||||
aChannel->GetServerTiming(getter_AddRefs(mServerTiming));
|
aChannel->GetNativeServerTiming(mServerTiming);
|
||||||
|
|
||||||
// The performance timing api essentially requires that the event timestamps
|
// The performance timing api essentially requires that the event timestamps
|
||||||
// have a strict relation with each other. The truth, however, is the
|
// have a strict relation with each other. The truth, however, is the
|
||||||
@@ -673,17 +673,16 @@ PerformanceTiming::IsTopLevelContentDocument() const
|
|||||||
return rootItem->ItemType() == nsIDocShellTreeItem::typeContent;
|
return rootItem->ItemType() == nsIDocShellTreeItem::typeContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIArray>
|
nsTArray<nsCOMPtr<nsIServerTiming>>
|
||||||
PerformanceTimingData::GetServerTiming() const
|
PerformanceTimingData::GetServerTiming()
|
||||||
{
|
{
|
||||||
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
|
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
|
||||||
!TimingAllowed() ||
|
!TimingAllowed() ||
|
||||||
nsContentUtils::ShouldResistFingerprinting()) {
|
nsContentUtils::ShouldResistFingerprinting()) {
|
||||||
return nullptr;
|
return nsTArray<nsCOMPtr<nsIServerTiming>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIArray> serverTiming = mServerTiming;
|
return nsTArray<nsCOMPtr<nsIServerTiming>>(mServerTiming);
|
||||||
return serverTiming.forget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "nsRFPService.h"
|
#include "nsRFPService.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
#include "Performance.h"
|
#include "Performance.h"
|
||||||
|
#include "nsITimedChannel.h"
|
||||||
|
|
||||||
class nsIHttpChannel;
|
class nsIHttpChannel;
|
||||||
class nsITimedChannel;
|
class nsITimedChannel;
|
||||||
@@ -169,7 +170,7 @@ public:
|
|||||||
return mTimingAllowed;
|
return mTimingAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIArray> GetServerTiming() const;
|
nsTArray<nsCOMPtr<nsIServerTiming>> GetServerTiming();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Checks if the resource is either same origin as the page that started
|
// Checks if the resource is either same origin as the page that started
|
||||||
@@ -178,7 +179,7 @@ private:
|
|||||||
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
|
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
|
||||||
nsITimedChannel* aChannel);
|
nsITimedChannel* aChannel);
|
||||||
|
|
||||||
nsCOMPtr<nsIArray> mServerTiming;
|
nsTArray<nsCOMPtr<nsIServerTiming>> mServerTiming;
|
||||||
nsString mNextHopProtocol;
|
nsString mNextHopProtocol;
|
||||||
|
|
||||||
TimeStamp mAsyncOpen;
|
TimeStamp mAsyncOpen;
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ interface nsIPrincipal;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class TimeStamp;
|
class TimeStamp;
|
||||||
}
|
}
|
||||||
|
#include "nsTArrayForwardDeclare.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
native TimeStamp(mozilla::TimeStamp);
|
native TimeStamp(mozilla::TimeStamp);
|
||||||
@@ -20,6 +22,8 @@ interface nsIServerTiming : nsISupports {
|
|||||||
[must_use] readonly attribute ACString description;
|
[must_use] readonly attribute ACString description;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[ref] native nsServerTimingArrayRef(nsTArray<nsCOMPtr<nsIServerTiming>>);
|
||||||
|
|
||||||
// All properties return zero if the value is not available
|
// All properties return zero if the value is not available
|
||||||
[scriptable, uuid(ca63784d-959c-4c3a-9a59-234a2a520de0)]
|
[scriptable, uuid(ca63784d-959c-4c3a-9a59-234a2a520de0)]
|
||||||
interface nsITimedChannel : nsISupports {
|
interface nsITimedChannel : nsISupports {
|
||||||
@@ -110,4 +114,5 @@ interface nsITimedChannel : nsISupports {
|
|||||||
[noscript] attribute boolean reportResourceTiming;
|
[noscript] attribute boolean reportResourceTiming;
|
||||||
|
|
||||||
readonly attribute nsIArray serverTiming;
|
readonly attribute nsIArray serverTiming;
|
||||||
|
nsServerTimingArrayRef getNativeServerTiming();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4566,7 +4566,7 @@ HttpBaseChannel::CallTypeSniffers(void *aClosure, const uint8_t *aData,
|
|||||||
template <class T>
|
template <class T>
|
||||||
static void
|
static void
|
||||||
ParseServerTimingHeader(const nsAutoPtr<T> &aHeader,
|
ParseServerTimingHeader(const nsAutoPtr<T> &aHeader,
|
||||||
nsIMutableArray* aOutput)
|
nsTArray<nsCOMPtr<nsIServerTiming>>& aOutput)
|
||||||
{
|
{
|
||||||
if (!aHeader) {
|
if (!aHeader) {
|
||||||
return;
|
return;
|
||||||
@@ -4582,27 +4582,39 @@ ParseServerTimingHeader(const nsAutoPtr<T> &aHeader,
|
|||||||
parser.Parse();
|
parser.Parse();
|
||||||
|
|
||||||
nsTArray<nsCOMPtr<nsIServerTiming>> array = parser.TakeServerTimingHeaders();
|
nsTArray<nsCOMPtr<nsIServerTiming>> array = parser.TakeServerTimingHeaders();
|
||||||
for (const auto &data : array) {
|
aOutput.AppendElements(array);
|
||||||
aOutput->AppendElement(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpBaseChannel::GetServerTiming(nsIArray **aServerTiming)
|
HttpBaseChannel::GetServerTiming(nsIArray **aServerTiming)
|
||||||
{
|
{
|
||||||
|
nsresult rv;
|
||||||
NS_ENSURE_ARG_POINTER(aServerTiming);
|
NS_ENSURE_ARG_POINTER(aServerTiming);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsTArray<nsCOMPtr<nsIServerTiming>> data;
|
||||||
|
rv = GetNativeServerTiming(data);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
for (const auto &entry : data) {
|
||||||
|
array->AppendElement(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
array.forget(aServerTiming);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
HttpBaseChannel::GetNativeServerTiming(nsTArray<nsCOMPtr<nsIServerTiming>>& aServerTiming)
|
||||||
|
{
|
||||||
|
aServerTiming.Clear();
|
||||||
|
|
||||||
bool isHTTPS = false;
|
bool isHTTPS = false;
|
||||||
if (NS_SUCCEEDED(mURI->SchemeIs("https", &isHTTPS)) && isHTTPS) {
|
if (NS_SUCCEEDED(mURI->SchemeIs("https", &isHTTPS)) && isHTTPS) {
|
||||||
nsTArray<nsCOMPtr<nsIServerTiming>> data;
|
ParseServerTimingHeader(mResponseHead, aServerTiming);
|
||||||
nsresult rv = NS_OK;
|
ParseServerTimingHeader(mResponseTrailers, aServerTiming);
|
||||||
nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
ParseServerTimingHeader(mResponseHead, array);
|
|
||||||
ParseServerTimingHeader(mResponseTrailers, array);
|
|
||||||
|
|
||||||
array.forget(aServerTiming);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|||||||
@@ -901,6 +901,12 @@ NullHttpChannel::GetServerTiming(nsIArray **aServerTiming)
|
|||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
NullHttpChannel::GetNativeServerTiming(nsTArray<nsCOMPtr<nsIServerTiming>>& aServerTiming)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
#define IMPL_TIMING_ATTR(name) \
|
#define IMPL_TIMING_ATTR(name) \
|
||||||
NS_IMETHODIMP \
|
NS_IMETHODIMP \
|
||||||
NullHttpChannel::Get##name##Time(PRTime* _retval) { \
|
NullHttpChannel::Get##name##Time(PRTime* _retval) { \
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
class nsServerTiming final : public nsIServerTiming
|
class nsServerTiming final : public nsIServerTiming
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSISERVERTIMING
|
NS_DECL_NSISERVERTIMING
|
||||||
|
|
||||||
nsServerTiming() = default;
|
nsServerTiming() = default;
|
||||||
|
|||||||
Reference in New Issue
Block a user