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:
Valentin Gosu
2018-04-24 13:04:12 +02:00
parent decbd92350
commit 5a8b6a068c
7 changed files with 48 additions and 34 deletions

View File

@@ -98,19 +98,10 @@ PerformanceResourceTiming::GetServerTiming(
return;
}
nsCOMPtr<nsIArray> serverTimingArray = mTimingData->GetServerTiming();
if (!serverTimingArray) {
return;
}
uint32_t length = 0;
if (NS_WARN_IF(NS_FAILED(serverTimingArray->GetLength(&length)))) {
return;
}
nsTArray<nsCOMPtr<nsIServerTiming>> serverTimingArray = mTimingData->GetServerTiming();
uint32_t length = serverTimingArray.Length();
for (uint32_t index = 0; index < length; ++index) {
nsCOMPtr<nsIServerTiming> serverTiming =
do_QueryElementAt(serverTimingArray, index);
nsCOMPtr<nsIServerTiming> serverTiming = serverTimingArray.ElementAt(index);
MOZ_ASSERT(serverTiming);
aRetval.AppendElement(

View File

@@ -162,7 +162,7 @@ PerformanceTimingData::PerformanceTimingData(nsITimedChannel* aChannel,
// ServiceWorker interception responseStart?
aChannel->GetHandleFetchEventEnd(&mWorkerResponseEnd);
aChannel->GetServerTiming(getter_AddRefs(mServerTiming));
aChannel->GetNativeServerTiming(mServerTiming);
// The performance timing api essentially requires that the event timestamps
// have a strict relation with each other. The truth, however, is the
@@ -673,17 +673,16 @@ PerformanceTiming::IsTopLevelContentDocument() const
return rootItem->ItemType() == nsIDocShellTreeItem::typeContent;
}
already_AddRefed<nsIArray>
PerformanceTimingData::GetServerTiming() const
nsTArray<nsCOMPtr<nsIServerTiming>>
PerformanceTimingData::GetServerTiming()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized() ||
!TimingAllowed() ||
nsContentUtils::ShouldResistFingerprinting()) {
return nullptr;
return nsTArray<nsCOMPtr<nsIServerTiming>>();
}
nsCOMPtr<nsIArray> serverTiming = mServerTiming;
return serverTiming.forget();
return nsTArray<nsCOMPtr<nsIServerTiming>>(mServerTiming);
}
} // dom namespace

View File

@@ -13,6 +13,7 @@
#include "nsRFPService.h"
#include "nsWrapperCache.h"
#include "Performance.h"
#include "nsITimedChannel.h"
class nsIHttpChannel;
class nsITimedChannel;
@@ -169,7 +170,7 @@ public:
return mTimingAllowed;
}
already_AddRefed<nsIArray> GetServerTiming() const;
nsTArray<nsCOMPtr<nsIServerTiming>> GetServerTiming();
private:
// Checks if the resource is either same origin as the page that started
@@ -178,7 +179,7 @@ private:
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
nsITimedChannel* aChannel);
nsCOMPtr<nsIArray> mServerTiming;
nsTArray<nsCOMPtr<nsIServerTiming>> mServerTiming;
nsString mNextHopProtocol;
TimeStamp mAsyncOpen;

View File

@@ -9,6 +9,8 @@ interface nsIPrincipal;
namespace mozilla {
class TimeStamp;
}
#include "nsTArrayForwardDeclare.h"
#include "nsCOMPtr.h"
%}
native TimeStamp(mozilla::TimeStamp);
@@ -20,6 +22,8 @@ interface nsIServerTiming : nsISupports {
[must_use] readonly attribute ACString description;
};
[ref] native nsServerTimingArrayRef(nsTArray<nsCOMPtr<nsIServerTiming>>);
// All properties return zero if the value is not available
[scriptable, uuid(ca63784d-959c-4c3a-9a59-234a2a520de0)]
interface nsITimedChannel : nsISupports {
@@ -110,4 +114,5 @@ interface nsITimedChannel : nsISupports {
[noscript] attribute boolean reportResourceTiming;
readonly attribute nsIArray serverTiming;
nsServerTimingArrayRef getNativeServerTiming();
};

View File

@@ -4566,7 +4566,7 @@ HttpBaseChannel::CallTypeSniffers(void *aClosure, const uint8_t *aData,
template <class T>
static void
ParseServerTimingHeader(const nsAutoPtr<T> &aHeader,
nsIMutableArray* aOutput)
nsTArray<nsCOMPtr<nsIServerTiming>>& aOutput)
{
if (!aHeader) {
return;
@@ -4582,27 +4582,39 @@ ParseServerTimingHeader(const nsAutoPtr<T> &aHeader,
parser.Parse();
nsTArray<nsCOMPtr<nsIServerTiming>> array = parser.TakeServerTimingHeaders();
for (const auto &data : array) {
aOutput->AppendElement(data);
}
aOutput.AppendElements(array);
}
NS_IMETHODIMP
HttpBaseChannel::GetServerTiming(nsIArray **aServerTiming)
{
nsresult rv;
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;
if (NS_SUCCEEDED(mURI->SchemeIs("https", &isHTTPS)) && isHTTPS) {
nsTArray<nsCOMPtr<nsIServerTiming>> data;
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
ParseServerTimingHeader(mResponseHead, array);
ParseServerTimingHeader(mResponseTrailers, array);
array.forget(aServerTiming);
ParseServerTimingHeader(mResponseHead, aServerTiming);
ParseServerTimingHeader(mResponseTrailers, aServerTiming);
}
return NS_OK;

View File

@@ -901,6 +901,12 @@ NullHttpChannel::GetServerTiming(nsIArray **aServerTiming)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::GetNativeServerTiming(nsTArray<nsCOMPtr<nsIServerTiming>>& aServerTiming)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
#define IMPL_TIMING_ATTR(name) \
NS_IMETHODIMP \
NullHttpChannel::Get##name##Time(PRTime* _retval) { \

View File

@@ -14,7 +14,7 @@
class nsServerTiming final : public nsIServerTiming
{
public:
NS_DECL_ISUPPORTS
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISERVERTIMING
nsServerTiming() = default;