Bug 1857217 - Understand the IPC delays introduced by socket process, r=acreskey,necko-reviewers,valentin

Differential Revision: https://phabricator.services.mozilla.com/D190182
This commit is contained in:
Kershaw Chang 2023-10-10 15:09:18 +00:00
parent 6442aff82b
commit ff5a7836c1
22 changed files with 283 additions and 124 deletions

View file

@ -21,7 +21,8 @@ void BackgroundDataBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
} }
mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnTransportAndData( mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnTransportAndData(
const uint64_t& offset, const uint32_t& count, const nsACString& data) { const uint64_t& offset, const uint32_t& count, const nsACString& data,
const TimeStamp& aOnDataAvailableStartTime) {
if (!mBgChild) { if (!mBgChild) {
return IPC_OK(); return IPC_OK();
} }
@ -32,13 +33,15 @@ mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnTransportAndData(
} }
return mBgChild->RecvOnTransportAndData(NS_OK, NS_NET_STATUS_RECEIVING_FROM, return mBgChild->RecvOnTransportAndData(NS_OK, NS_NET_STATUS_RECEIVING_FROM,
offset, count, data, true); offset, count, data, true,
aOnDataAvailableStartTime);
} }
mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnStopRequest( mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnStopRequest(
nsresult aStatus, const ResourceTimingStructArgs& aTiming, nsresult aStatus, const ResourceTimingStructArgs& aTiming,
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const nsHttpHeaderArray& aResponseTrailers) { const nsHttpHeaderArray& aResponseTrailers,
const TimeStamp& aOnStopRequestStartTime) {
if (!mBgChild) { if (!mBgChild) {
return IPC_OK(); return IPC_OK();
} }
@ -48,9 +51,9 @@ mozilla::ipc::IPCResult BackgroundDataBridgeChild::RecvOnStopRequest(
return IPC_OK(); return IPC_OK();
} }
return mBgChild->RecvOnStopRequest(aStatus, aTiming, aLastActiveTabOptHit, return mBgChild->RecvOnStopRequest(
aResponseTrailers, aStatus, aTiming, aLastActiveTabOptHit, aResponseTrailers,
nsTArray<ConsoleReportCollected>(), true); nsTArray<ConsoleReportCollected>(), true, aOnStopRequestStartTime);
} }
} // namespace net } // namespace net

View file

@ -25,13 +25,14 @@ class BackgroundDataBridgeChild final : public PBackgroundDataBridgeChild {
RefPtr<HttpBackgroundChannelChild> mBgChild; RefPtr<HttpBackgroundChannelChild> mBgChild;
public: public:
mozilla::ipc::IPCResult RecvOnTransportAndData(const uint64_t& offset, mozilla::ipc::IPCResult RecvOnTransportAndData(
const uint32_t& count, const uint64_t& offset, const uint32_t& count, const nsACString& data,
const nsACString& data); const TimeStamp& aOnDataAvailableStartTime);
mozilla::ipc::IPCResult RecvOnStopRequest( mozilla::ipc::IPCResult RecvOnStopRequest(
nsresult aStatus, const ResourceTimingStructArgs& aTiming, nsresult aStatus, const ResourceTimingStructArgs& aTiming,
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const nsHttpHeaderArray& aResponseTrailers); const nsHttpHeaderArray& aResponseTrailers,
const TimeStamp& aOnStopRequestStartTime);
}; };
} // namespace net } // namespace net

View file

@ -42,18 +42,20 @@ void BackgroundDataBridgeParent::Destroy() {
void BackgroundDataBridgeParent::OnStopRequest( void BackgroundDataBridgeParent::OnStopRequest(
nsresult aStatus, const ResourceTimingStructArgs& aTiming, nsresult aStatus, const ResourceTimingStructArgs& aTiming,
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const nsHttpHeaderArray& aResponseTrailers) { const nsHttpHeaderArray& aResponseTrailers,
const TimeStamp& aOnStopRequestStart) {
RefPtr<BackgroundDataBridgeParent> self = this; RefPtr<BackgroundDataBridgeParent> self = this;
MOZ_ALWAYS_SUCCEEDS(mBackgroundThread->Dispatch( MOZ_ALWAYS_SUCCEEDS(mBackgroundThread->Dispatch(
NS_NewRunnableFunction( NS_NewRunnableFunction("BackgroundDataBridgeParent::OnStopRequest",
"BackgroundDataBridgeParent::OnStopRequest", [self, aStatus, aTiming, aLastActiveTabOptHit,
[self, aStatus, aTiming, aLastActiveTabOptHit, aResponseTrailers]() { aResponseTrailers, aOnStopRequestStart]() {
if (self->CanSend()) { if (self->CanSend()) {
Unused << self->SendOnStopRequest( Unused << self->SendOnStopRequest(
aStatus, aTiming, aLastActiveTabOptHit, aResponseTrailers); aStatus, aTiming, aLastActiveTabOptHit,
self->Close(); aResponseTrailers, aOnStopRequestStart);
} self->Close();
}), }
}),
NS_DISPATCH_NORMAL)); NS_DISPATCH_NORMAL));
} }

View file

@ -20,7 +20,8 @@ class BackgroundDataBridgeParent final : public PBackgroundDataBridgeParent {
void Destroy(); void Destroy();
void OnStopRequest(nsresult aStatus, const ResourceTimingStructArgs& aTiming, void OnStopRequest(nsresult aStatus, const ResourceTimingStructArgs& aTiming,
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const nsHttpHeaderArray& aResponseTrailers); const nsHttpHeaderArray& aResponseTrailers,
const TimeStamp& aOnStopRequestStart);
private: private:
virtual ~BackgroundDataBridgeParent() = default; virtual ~BackgroundDataBridgeParent() = default;

View file

@ -185,7 +185,8 @@ IPCResult HttpBackgroundChannelChild::RecvOnStartRequest(
const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead, const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders, const nsHttpHeaderArray& aRequestHeaders,
const HttpChannelOnStartRequestArgs& aArgs, const HttpChannelOnStartRequestArgs& aArgs,
const HttpChannelAltDataStream& aAltData) { const HttpChannelAltDataStream& aAltData,
const TimeStamp& aOnStartRequestStart) {
LOG(( LOG((
"HttpBackgroundChannelChild::RecvOnStartRequest [this=%p, status=%" PRIx32 "HttpBackgroundChannelChild::RecvOnStartRequest [this=%p, status=%" PRIx32
"]\n", "]\n",
@ -200,7 +201,8 @@ IPCResult HttpBackgroundChannelChild::RecvOnStartRequest(
aArgs.dataFromSocketProcess() ? ODA_FROM_SOCKET : ODA_FROM_PARENT; aArgs.dataFromSocketProcess() ? ODA_FROM_SOCKET : ODA_FROM_PARENT;
mChannelChild->ProcessOnStartRequest(aResponseHead, aUseResponseHead, mChannelChild->ProcessOnStartRequest(aResponseHead, aUseResponseHead,
aRequestHeaders, aArgs, aAltData); aRequestHeaders, aArgs, aAltData,
aOnStartRequestStart);
// Allow to queue other runnable since OnStartRequest Event already hits the // Allow to queue other runnable since OnStartRequest Event already hits the
// child's mEventQ. // child's mEventQ.
OnStartRequestReceived(aArgs.multiPartID()); OnStartRequestReceived(aArgs.multiPartID());
@ -211,11 +213,13 @@ IPCResult HttpBackgroundChannelChild::RecvOnStartRequest(
IPCResult HttpBackgroundChannelChild::RecvOnTransportAndData( IPCResult HttpBackgroundChannelChild::RecvOnTransportAndData(
const nsresult& aChannelStatus, const nsresult& aTransportStatus, const nsresult& aChannelStatus, const nsresult& aTransportStatus,
const uint64_t& aOffset, const uint32_t& aCount, const nsACString& aData, const uint64_t& aOffset, const uint32_t& aCount, const nsACString& aData,
const bool& aDataFromSocketProcess) { const bool& aDataFromSocketProcess,
const TimeStamp& aOnDataAvailableStart) {
RefPtr<HttpBackgroundChannelChild> self = this; RefPtr<HttpBackgroundChannelChild> self = this;
std::function<void()> callProcessOnTransportAndData = std::function<void()> callProcessOnTransportAndData =
[self, aChannelStatus, aTransportStatus, aOffset, aCount, [self, aChannelStatus, aTransportStatus, aOffset, aCount,
data = nsCString(aData), aDataFromSocketProcess]() { data = nsCString(aData), aDataFromSocketProcess,
aOnDataAvailableStart]() {
LOG( LOG(
("HttpBackgroundChannelChild::RecvOnTransportAndData [this=%p, " ("HttpBackgroundChannelChild::RecvOnTransportAndData [this=%p, "
"aDataFromSocketProcess=%d, mFirstODASource=%d]\n", "aDataFromSocketProcess=%d, mFirstODASource=%d]\n",
@ -243,7 +247,8 @@ IPCResult HttpBackgroundChannelChild::RecvOnTransportAndData(
} }
self->mChannelChild->ProcessOnTransportAndData( self->mChannelChild->ProcessOnTransportAndData(
aChannelStatus, aTransportStatus, aOffset, aCount, data); aChannelStatus, aTransportStatus, aOffset, aCount, data,
aOnDataAvailableStart);
}; };
// Bug 1641336: Race only happens if the data is from socket process. // Bug 1641336: Race only happens if the data is from socket process.
@ -267,7 +272,7 @@ IPCResult HttpBackgroundChannelChild::RecvOnStopRequest(
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const nsHttpHeaderArray& aResponseTrailers, const nsHttpHeaderArray& aResponseTrailers,
nsTArray<ConsoleReportCollected>&& aConsoleReports, nsTArray<ConsoleReportCollected>&& aConsoleReports,
const bool& aFromSocketProcess) { const bool& aFromSocketProcess, const TimeStamp& aOnStopRequestStart) {
LOG( LOG(
("HttpBackgroundChannelChild::RecvOnStopRequest [this=%p, " ("HttpBackgroundChannelChild::RecvOnStopRequest [this=%p, "
"aFromSocketProcess=%d, mFirstODASource=%d]\n", "aFromSocketProcess=%d, mFirstODASource=%d]\n",
@ -295,10 +300,10 @@ IPCResult HttpBackgroundChannelChild::RecvOnStopRequest(
"HttpBackgroundChannelChild::RecvOnStopRequest", "HttpBackgroundChannelChild::RecvOnStopRequest",
[self, aChannelStatus, aTiming, aLastActiveTabOptHit, aResponseTrailers, [self, aChannelStatus, aTiming, aLastActiveTabOptHit, aResponseTrailers,
consoleReports = CopyableTArray{std::move(aConsoleReports)}, consoleReports = CopyableTArray{std::move(aConsoleReports)},
aFromSocketProcess]() mutable { aFromSocketProcess, aOnStopRequestStart]() mutable {
self->RecvOnStopRequest(aChannelStatus, aTiming, aLastActiveTabOptHit, self->RecvOnStopRequest(aChannelStatus, aTiming, aLastActiveTabOptHit,
aResponseTrailers, std::move(consoleReports), aResponseTrailers, std::move(consoleReports),
aFromSocketProcess); aFromSocketProcess, aOnStopRequestStart);
}); });
mQueuedRunnables.AppendElement(task.forget()); mQueuedRunnables.AppendElement(task.forget());
@ -308,9 +313,9 @@ IPCResult HttpBackgroundChannelChild::RecvOnStopRequest(
if (mFirstODASource != ODA_FROM_SOCKET) { if (mFirstODASource != ODA_FROM_SOCKET) {
if (!aFromSocketProcess) { if (!aFromSocketProcess) {
mOnStopRequestCalled = true; mOnStopRequestCalled = true;
mChannelChild->ProcessOnStopRequest(aChannelStatus, aTiming, mChannelChild->ProcessOnStopRequest(
aResponseTrailers, aChannelStatus, aTiming, aResponseTrailers,
std::move(aConsoleReports), false); std::move(aConsoleReports), false, aOnStopRequestStart);
} }
return IPC_OK(); return IPC_OK();
} }
@ -320,9 +325,9 @@ IPCResult HttpBackgroundChannelChild::RecvOnStopRequest(
if (aFromSocketProcess) { if (aFromSocketProcess) {
MOZ_ASSERT(!mOnStopRequestCalled); MOZ_ASSERT(!mOnStopRequestCalled);
mOnStopRequestCalled = true; mOnStopRequestCalled = true;
mChannelChild->ProcessOnStopRequest(aChannelStatus, aTiming, mChannelChild->ProcessOnStopRequest(
aResponseTrailers, aChannelStatus, aTiming, aResponseTrailers, std::move(aConsoleReports),
std::move(aConsoleReports), true); true, aOnStopRequestStart);
if (mConsoleReportTask) { if (mConsoleReportTask) {
mConsoleReportTask(); mConsoleReportTask();
mConsoleReportTask = nullptr; mConsoleReportTask = nullptr;

View file

@ -57,21 +57,23 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
const bool& aUseResponseHead, const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders, const nsHttpHeaderArray& aRequestHeaders,
const HttpChannelOnStartRequestArgs& aArgs, const HttpChannelOnStartRequestArgs& aArgs,
const HttpChannelAltDataStream& aAltData); const HttpChannelAltDataStream& aAltData,
const TimeStamp& aOnStartRequestStart);
IPCResult RecvOnTransportAndData(const nsresult& aChannelStatus, IPCResult RecvOnTransportAndData(const nsresult& aChannelStatus,
const nsresult& aTransportStatus, const nsresult& aTransportStatus,
const uint64_t& aOffset, const uint64_t& aOffset,
const uint32_t& aCount, const uint32_t& aCount,
const nsACString& aData, const nsACString& aData,
const bool& aDataFromSocketProcess); const bool& aDataFromSocketProcess,
const TimeStamp& aOnDataAvailableStart);
IPCResult RecvOnStopRequest( IPCResult RecvOnStopRequest(
const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming, const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming,
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const nsHttpHeaderArray& aResponseTrailers, const nsHttpHeaderArray& aResponseTrailers,
nsTArray<ConsoleReportCollected>&& aConsoleReports, nsTArray<ConsoleReportCollected>&& aConsoleReports,
const bool& aFromSocketProcess); const bool& aFromSocketProcess, const TimeStamp& aOnStopRequestStart);
IPCResult RecvOnConsoleReport( IPCResult RecvOnConsoleReport(
nsTArray<ConsoleReportCollected>&& aConsoleReports); nsTArray<ConsoleReportCollected>&& aConsoleReports);

View file

@ -147,7 +147,8 @@ bool HttpBackgroundChannelParent::OnStartRequest(
const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead, const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders, const nsHttpHeaderArray& aRequestHeaders,
const HttpChannelOnStartRequestArgs& aArgs, const HttpChannelOnStartRequestArgs& aArgs,
const nsCOMPtr<nsICacheEntry>& aAltDataSource) { const nsCOMPtr<nsICacheEntry>& aAltDataSource,
TimeStamp aOnStartRequestStart) {
LOG(("HttpBackgroundChannelParent::OnStartRequest [this=%p]\n", this)); LOG(("HttpBackgroundChannelParent::OnStartRequest [this=%p]\n", this));
AssertIsInMainProcess(); AssertIsInMainProcess();
@ -158,12 +159,14 @@ bool HttpBackgroundChannelParent::OnStartRequest(
if (!IsOnBackgroundThread()) { if (!IsOnBackgroundThread()) {
MutexAutoLock lock(mBgThreadMutex); MutexAutoLock lock(mBgThreadMutex);
nsresult rv = mBackgroundThread->Dispatch( nsresult rv = mBackgroundThread->Dispatch(
NewRunnableMethod< NewRunnableMethod<const nsHttpResponseHead, const bool,
const nsHttpResponseHead, const bool, const nsHttpHeaderArray, const nsHttpHeaderArray,
const HttpChannelOnStartRequestArgs, const nsCOMPtr<nsICacheEntry>>( const HttpChannelOnStartRequestArgs,
const nsCOMPtr<nsICacheEntry>, TimeStamp>(
"net::HttpBackgroundChannelParent::OnStartRequest", this, "net::HttpBackgroundChannelParent::OnStartRequest", this,
&HttpBackgroundChannelParent::OnStartRequest, aResponseHead, &HttpBackgroundChannelParent::OnStartRequest, aResponseHead,
aUseResponseHead, aRequestHeaders, aArgs, aAltDataSource), aUseResponseHead, aRequestHeaders, aArgs, aAltDataSource,
aOnStartRequestStart),
NS_DISPATCH_NORMAL); NS_DISPATCH_NORMAL);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
@ -189,12 +192,13 @@ bool HttpBackgroundChannelParent::OnStartRequest(
} }
return SendOnStartRequest(aResponseHead, aUseResponseHead, aRequestHeaders, return SendOnStartRequest(aResponseHead, aUseResponseHead, aRequestHeaders,
aArgs, altData); aArgs, altData, aOnStartRequestStart);
} }
bool HttpBackgroundChannelParent::OnTransportAndData( bool HttpBackgroundChannelParent::OnTransportAndData(
const nsresult& aChannelStatus, const nsresult& aTransportStatus, const nsresult& aChannelStatus, const nsresult& aTransportStatus,
const uint64_t& aOffset, const uint32_t& aCount, const nsCString& aData) { const uint64_t& aOffset, const uint32_t& aCount, const nsCString& aData,
TimeStamp aOnDataAvailableStart) {
LOG(("HttpBackgroundChannelParent::OnTransportAndData [this=%p]\n", this)); LOG(("HttpBackgroundChannelParent::OnTransportAndData [this=%p]\n", this));
AssertIsInMainProcess(); AssertIsInMainProcess();
@ -206,10 +210,10 @@ bool HttpBackgroundChannelParent::OnTransportAndData(
MutexAutoLock lock(mBgThreadMutex); MutexAutoLock lock(mBgThreadMutex);
nsresult rv = mBackgroundThread->Dispatch( nsresult rv = mBackgroundThread->Dispatch(
NewRunnableMethod<const nsresult, const nsresult, const uint64_t, NewRunnableMethod<const nsresult, const nsresult, const uint64_t,
const uint32_t, const nsCString>( const uint32_t, const nsCString, TimeStamp>(
"net::HttpBackgroundChannelParent::OnTransportAndData", this, "net::HttpBackgroundChannelParent::OnTransportAndData", this,
&HttpBackgroundChannelParent::OnTransportAndData, aChannelStatus, &HttpBackgroundChannelParent::OnTransportAndData, aChannelStatus,
aTransportStatus, aOffset, aCount, aData), aTransportStatus, aOffset, aCount, aData, aOnDataAvailableStart),
NS_DISPATCH_NORMAL); NS_DISPATCH_NORMAL);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
@ -219,10 +223,12 @@ bool HttpBackgroundChannelParent::OnTransportAndData(
nsHttp::SendFunc<nsDependentCSubstring> sendFunc = nsHttp::SendFunc<nsDependentCSubstring> sendFunc =
[self = UnsafePtr<HttpBackgroundChannelParent>(this), aChannelStatus, [self = UnsafePtr<HttpBackgroundChannelParent>(this), aChannelStatus,
aTransportStatus](const nsDependentCSubstring& aData, uint64_t aOffset, aTransportStatus,
uint32_t aCount) { aOnDataAvailableStart](const nsDependentCSubstring& aData,
uint64_t aOffset, uint32_t aCount) {
return self->SendOnTransportAndData(aChannelStatus, aTransportStatus, return self->SendOnTransportAndData(aChannelStatus, aTransportStatus,
aOffset, aCount, aData, false); aOffset, aCount, aData, false,
aOnDataAvailableStart);
}; };
return nsHttp::SendDataInChunks(aData, aOffset, aCount, sendFunc); return nsHttp::SendDataInChunks(aData, aOffset, aCount, sendFunc);
@ -231,7 +237,8 @@ bool HttpBackgroundChannelParent::OnTransportAndData(
bool HttpBackgroundChannelParent::OnStopRequest( bool HttpBackgroundChannelParent::OnStopRequest(
const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming, const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming,
const nsHttpHeaderArray& aResponseTrailers, const nsHttpHeaderArray& aResponseTrailers,
const nsTArray<ConsoleReportCollected>& aConsoleReports) { const nsTArray<ConsoleReportCollected>& aConsoleReports,
TimeStamp aOnStopRequestStart) {
LOG( LOG(
("HttpBackgroundChannelParent::OnStopRequest [this=%p " ("HttpBackgroundChannelParent::OnStopRequest [this=%p "
"status=%" PRIx32 "]\n", "status=%" PRIx32 "]\n",
@ -247,10 +254,11 @@ bool HttpBackgroundChannelParent::OnStopRequest(
nsresult rv = mBackgroundThread->Dispatch( nsresult rv = mBackgroundThread->Dispatch(
NewRunnableMethod<const nsresult, const ResourceTimingStructArgs, NewRunnableMethod<const nsresult, const ResourceTimingStructArgs,
const nsHttpHeaderArray, const nsHttpHeaderArray,
const CopyableTArray<ConsoleReportCollected>>( const CopyableTArray<ConsoleReportCollected>,
TimeStamp>(
"net::HttpBackgroundChannelParent::OnStopRequest", this, "net::HttpBackgroundChannelParent::OnStopRequest", this,
&HttpBackgroundChannelParent::OnStopRequest, aChannelStatus, &HttpBackgroundChannelParent::OnStopRequest, aChannelStatus,
aTiming, aResponseTrailers, aConsoleReports), aTiming, aResponseTrailers, aConsoleReports, aOnStopRequestStart),
NS_DISPATCH_NORMAL); NS_DISPATCH_NORMAL);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
@ -262,7 +270,8 @@ bool HttpBackgroundChannelParent::OnStopRequest(
TimeStamp lastActTabOpt = nsHttp::GetLastActiveTabLoadOptimizationHit(); TimeStamp lastActTabOpt = nsHttp::GetLastActiveTabLoadOptimizationHit();
return SendOnStopRequest(aChannelStatus, aTiming, lastActTabOpt, return SendOnStopRequest(aChannelStatus, aTiming, lastActTabOpt,
aResponseTrailers, aConsoleReports, false); aResponseTrailers, aConsoleReports, false,
aOnStopRequestStart);
} }
bool HttpBackgroundChannelParent::OnConsoleReport( bool HttpBackgroundChannelParent::OnConsoleReport(

View file

@ -44,19 +44,22 @@ class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent {
const bool& aUseResponseHead, const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders, const nsHttpHeaderArray& aRequestHeaders,
const HttpChannelOnStartRequestArgs& aArgs, const HttpChannelOnStartRequestArgs& aArgs,
const nsCOMPtr<nsICacheEntry>& aCacheEntry); const nsCOMPtr<nsICacheEntry>& aCacheEntry,
TimeStamp aOnStartRequestStart);
// To send OnTransportAndData message over background channel. // To send OnTransportAndData message over background channel.
bool OnTransportAndData(const nsresult& aChannelStatus, bool OnTransportAndData(const nsresult& aChannelStatus,
const nsresult& aTransportStatus, const nsresult& aTransportStatus,
const uint64_t& aOffset, const uint32_t& aCount, const uint64_t& aOffset, const uint32_t& aCount,
const nsCString& aData); const nsCString& aData,
TimeStamp aOnDataAvailableStart);
// To send OnStopRequest message over background channel. // To send OnStopRequest message over background channel.
bool OnStopRequest(const nsresult& aChannelStatus, bool OnStopRequest(const nsresult& aChannelStatus,
const ResourceTimingStructArgs& aTiming, const ResourceTimingStructArgs& aTiming,
const nsHttpHeaderArray& aResponseTrailers, const nsHttpHeaderArray& aResponseTrailers,
const nsTArray<ConsoleReportCollected>& aConsoleReports); const nsTArray<ConsoleReportCollected>& aConsoleReports,
TimeStamp aOnStopRequestStart);
// When ODA and OnStopRequest are sending from socket process to child // When ODA and OnStopRequest are sending from socket process to child
// process, this is the last IPC message sent from parent process. // process, this is the last IPC message sent from parent process.

View file

@ -572,6 +572,16 @@ class HttpBaseChannel : public nsHashPropertyBag,
return mCachedOpaqueResponseBlockingPref; return mCachedOpaqueResponseBlockingPref;
} }
TimeStamp GetOnStartRequestStartTime() const {
return mOnStartRequestStartTime;
}
TimeStamp GetDataAvailableStartTime() const {
return mOnDataAvailableStartTime;
}
TimeStamp GetOnStopRequestStartTime() const {
return mOnStopRequestStartTime;
}
protected: protected:
nsresult GetTopWindowURI(nsIURI* aURIBeingLoaded, nsIURI** aTopWindowURI); nsresult GetTopWindowURI(nsIURI* aURIBeingLoaded, nsIURI** aTopWindowURI);
@ -784,6 +794,9 @@ class HttpBaseChannel : public nsHashPropertyBag,
TimeStamp mDispatchFetchEventEnd; TimeStamp mDispatchFetchEventEnd;
TimeStamp mHandleFetchEventStart; TimeStamp mHandleFetchEventStart;
TimeStamp mHandleFetchEventEnd; TimeStamp mHandleFetchEventEnd;
TimeStamp mOnStartRequestStartTime;
TimeStamp mOnDataAvailableStartTime;
TimeStamp mOnStopRequestStartTime;
// copied from the transaction before we null out mTransaction // copied from the transaction before we null out mTransaction
// so that the timing can still be queried from OnStopRequest // so that the timing can still be queried from OnStopRequest
TimingStruct mTransactionTimings; TimingStruct mTransactionTimings;

View file

@ -347,15 +347,18 @@ void HttpChannelChild::ProcessOnStartRequest(
const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead, const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders, const nsHttpHeaderArray& aRequestHeaders,
const HttpChannelOnStartRequestArgs& aArgs, const HttpChannelOnStartRequestArgs& aArgs,
const HttpChannelAltDataStream& aAltData) { const HttpChannelAltDataStream& aAltData,
const TimeStamp& aOnStartRequestStartTime) {
LOG(("HttpChannelChild::ProcessOnStartRequest [this=%p]\n", this)); LOG(("HttpChannelChild::ProcessOnStartRequest [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread()); MOZ_ASSERT(OnSocketThread());
mAltDataInputStream = DeserializeIPCStream(aAltData.altDataInputStream()); mAltDataInputStream = DeserializeIPCStream(aAltData.altDataInputStream());
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent( mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this, [self = UnsafePtr<HttpChannelChild>(this), aResponseHead, this,
aUseResponseHead, aRequestHeaders, aArgs]() { [self = UnsafePtr<HttpChannelChild>(this), aResponseHead,
aUseResponseHead, aRequestHeaders, aArgs, aOnStartRequestStartTime]() {
self->mOnStartRequestStartTime = aOnStartRequestStartTime;
self->OnStartRequest(aResponseHead, aUseResponseHead, aRequestHeaders, self->OnStartRequest(aResponseHead, aUseResponseHead, aRequestHeaders,
aArgs); aArgs);
})); }));
@ -460,13 +463,18 @@ void HttpChannelChild::OnStartRequest(
aArgs.timing().transactionPending() - mAsyncOpenTime); aArgs.timing().transactionPending() - mAsyncOpenTime);
} }
const TimeStamp now = TimeStamp::Now();
if (!aArgs.timing().responseStart().IsNull()) { if (!aArgs.timing().responseStart().IsNull()) {
Telemetry::AccumulateTimeDelta( Telemetry::AccumulateTimeDelta(
Telemetry::NETWORK_RESPONSE_START_PARENT_TO_CONTENT_EXP_MS, cosString, Telemetry::NETWORK_RESPONSE_START_PARENT_TO_CONTENT_EXP_MS, cosString,
aArgs.timing().responseStart(), TimeStamp::Now()); aArgs.timing().responseStart(), now);
PerfStats::RecordMeasurement( PerfStats::RecordMeasurement(
PerfStats::Metric::HttpChannelResponseStartParentToContent, PerfStats::Metric::HttpChannelResponseStartParentToContent,
TimeStamp::Now() - aArgs.timing().responseStart()); now - aArgs.timing().responseStart());
}
if (!mOnStartRequestStartTime.IsNull()) {
PerfStats::RecordMeasurement(PerfStats::Metric::OnStartRequestToContent,
now - mOnStartRequestStartTime);
} }
StoreAllRedirectsSameOrigin(aArgs.allRedirectsSameOrigin()); StoreAllRedirectsSameOrigin(aArgs.allRedirectsSameOrigin());
@ -601,7 +609,8 @@ void HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest) {
void HttpChannelChild::ProcessOnTransportAndData( void HttpChannelChild::ProcessOnTransportAndData(
const nsresult& aChannelStatus, const nsresult& aTransportStatus, const nsresult& aChannelStatus, const nsresult& aTransportStatus,
const uint64_t& aOffset, const uint32_t& aCount, const nsACString& aData) { const uint64_t& aOffset, const uint32_t& aCount, const nsACString& aData,
const TimeStamp& aOnDataAvailableStartTime) {
LOG(("HttpChannelChild::ProcessOnTransportAndData [this=%p]\n", this)); LOG(("HttpChannelChild::ProcessOnTransportAndData [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread()); MOZ_ASSERT(OnSocketThread());
mEventQ->RunOrEnqueue(new ChannelFunctionEvent( mEventQ->RunOrEnqueue(new ChannelFunctionEvent(
@ -609,7 +618,9 @@ void HttpChannelChild::ProcessOnTransportAndData(
return self->GetODATarget(); return self->GetODATarget();
}, },
[self = UnsafePtr<HttpChannelChild>(this), aChannelStatus, [self = UnsafePtr<HttpChannelChild>(this), aChannelStatus,
aTransportStatus, aOffset, aCount, aData = nsCString(aData)]() { aTransportStatus, aOffset, aCount, aData = nsCString(aData),
aOnDataAvailableStartTime]() {
self->mOnDataAvailableStartTime = aOnDataAvailableStartTime;
self->OnTransportAndData(aChannelStatus, aTransportStatus, aOffset, self->OnTransportAndData(aChannelStatus, aTransportStatus, aOffset,
aCount, aData); aCount, aData);
})); }));
@ -630,6 +641,11 @@ void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
return; return;
} }
if (!mOnDataAvailableStartTime.IsNull()) {
PerfStats::RecordMeasurement(PerfStats::Metric::OnDataAvailableToContent,
TimeStamp::Now() - mOnDataAvailableStartTime);
}
// Hold queue lock throughout all three calls, else we might process a later // Hold queue lock throughout all three calls, else we might process a later
// necko msg in between them. // necko msg in between them.
AutoEventEnqueuer ensureSerialDispatch(mEventQ); AutoEventEnqueuer ensureSerialDispatch(mEventQ);
@ -788,8 +804,8 @@ void HttpChannelChild::DoOnDataAvailable(nsIRequest* aRequest,
void HttpChannelChild::ProcessOnStopRequest( void HttpChannelChild::ProcessOnStopRequest(
const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming, const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming,
const nsHttpHeaderArray& aResponseTrailers, const nsHttpHeaderArray& aResponseTrailers,
nsTArray<ConsoleReportCollected>&& aConsoleReports, nsTArray<ConsoleReportCollected>&& aConsoleReports, bool aFromSocketProcess,
bool aFromSocketProcess) { const TimeStamp& aOnStopRequestStartTime) {
LOG( LOG(
("HttpChannelChild::ProcessOnStopRequest [this=%p, " ("HttpChannelChild::ProcessOnStopRequest [this=%p, "
"aFromSocketProcess=%d]\n", "aFromSocketProcess=%d]\n",
@ -800,7 +816,8 @@ void HttpChannelChild::ProcessOnStopRequest(
this, [self = UnsafePtr<HttpChannelChild>(this), aChannelStatus, aTiming, this, [self = UnsafePtr<HttpChannelChild>(this), aChannelStatus, aTiming,
aResponseTrailers, aResponseTrailers,
consoleReports = CopyableTArray{aConsoleReports.Clone()}, consoleReports = CopyableTArray{aConsoleReports.Clone()},
aFromSocketProcess]() mutable { aFromSocketProcess, aOnStopRequestStartTime]() mutable {
self->mOnStopRequestStartTime = aOnStopRequestStartTime;
self->OnStopRequest(aChannelStatus, aTiming, aResponseTrailers); self->OnStopRequest(aChannelStatus, aTiming, aResponseTrailers);
if (!aFromSocketProcess) { if (!aFromSocketProcess) {
self->DoOnConsoleReport(std::move(consoleReports)); self->DoOnConsoleReport(std::move(consoleReports));
@ -959,6 +976,11 @@ void HttpChannelChild::OnStopRequest(
now - aTiming.responseEnd()); now - aTiming.responseEnd());
} }
if (!mOnStopRequestStartTime.IsNull()) {
PerfStats::RecordMeasurement(PerfStats::Metric::OnStopRequestToContent,
now - mOnStopRequestStartTime);
}
mResponseTrailers = MakeUnique<nsHttpHeaderArray>(aResponseTrailers); mResponseTrailers = MakeUnique<nsHttpHeaderArray>(aResponseTrailers);
DoPreOnStopRequest(aChannelStatus); DoPreOnStopRequest(aChannelStatus);

View file

@ -208,7 +208,8 @@ class HttpChannelChild final : public PHttpChannelChild,
const bool& aUseResponseHead, const bool& aUseResponseHead,
const nsHttpHeaderArray& aRequestHeaders, const nsHttpHeaderArray& aRequestHeaders,
const HttpChannelOnStartRequestArgs& aArgs, const HttpChannelOnStartRequestArgs& aArgs,
const HttpChannelAltDataStream& aAltData); const HttpChannelAltDataStream& aAltData,
const TimeStamp& aOnStartRequestStartTime);
// Callbacks while receiving OnTransportAndData/OnStopRequest/OnProgress/ // Callbacks while receiving OnTransportAndData/OnStopRequest/OnProgress/
// OnStatus/FlushedForDiversion/DivertMessages on background IPC channel. // OnStatus/FlushedForDiversion/DivertMessages on background IPC channel.
@ -216,12 +217,14 @@ class HttpChannelChild final : public PHttpChannelChild,
const nsresult& aTransportStatus, const nsresult& aTransportStatus,
const uint64_t& aOffset, const uint64_t& aOffset,
const uint32_t& aCount, const uint32_t& aCount,
const nsACString& aData); const nsACString& aData,
const TimeStamp& aOnDataAvailableStartTime);
void ProcessOnStopRequest(const nsresult& aChannelStatus, void ProcessOnStopRequest(const nsresult& aChannelStatus,
const ResourceTimingStructArgs& aTiming, const ResourceTimingStructArgs& aTiming,
const nsHttpHeaderArray& aResponseTrailers, const nsHttpHeaderArray& aResponseTrailers,
nsTArray<ConsoleReportCollected>&& aConsoleReports, nsTArray<ConsoleReportCollected>&& aConsoleReports,
bool aFromSocketProcess); bool aFromSocketProcess,
const TimeStamp& aOnStopRequestStartTime);
void ProcessOnConsoleReport( void ProcessOnConsoleReport(
nsTArray<ConsoleReportCollected>&& aConsoleReports); nsTArray<ConsoleReportCollected>&& aConsoleReports);

View file

@ -1333,7 +1333,7 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) {
!mBgParent->OnStartRequest( !mBgParent->OnStartRequest(
*responseHead, useResponseHead, *responseHead, useResponseHead,
cleanedUpRequest ? cleanedUpRequestHeaders : requestHead->Headers(), cleanedUpRequest ? cleanedUpRequestHeaders : requestHead->Headers(),
args, altDataSource)) { args, altDataSource, chan->GetOnStartRequestStartTime())) {
rv = NS_ERROR_UNEXPECTED; rv = NS_ERROR_UNEXPECTED;
} }
requestHead->Exit(); requestHead->Exit();
@ -1382,8 +1382,10 @@ HttpChannelParent::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
nsTArray<ConsoleReportCollected> consoleReports; nsTArray<ConsoleReportCollected> consoleReports;
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(mChannel); RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(mChannel);
TimeStamp onStopRequestStart;
if (httpChannel) { if (httpChannel) {
httpChannel->StealConsoleReports(consoleReports); httpChannel->StealConsoleReports(consoleReports);
onStopRequestStart = httpChannel->GetOnStopRequestStartTime();
} }
// Either IPC channel is closed or background channel // Either IPC channel is closed or background channel
@ -1404,7 +1406,7 @@ HttpChannelParent::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
!mBgParent->OnStopRequest( !mBgParent->OnStopRequest(
aStatusCode, GetTimingAttributes(mChannel), aStatusCode, GetTimingAttributes(mChannel),
responseTrailer ? *responseTrailer : nsHttpHeaderArray(), responseTrailer ? *responseTrailer : nsHttpHeaderArray(),
consoleReports)) { consoleReports, onStopRequestStart)) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
@ -1498,10 +1500,12 @@ HttpChannelParent::OnDataAvailable(nsIRequest* aRequest,
nsresult transportStatus = NS_NET_STATUS_RECEIVING_FROM; nsresult transportStatus = NS_NET_STATUS_RECEIVING_FROM;
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel); RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
TimeStamp onDataAvailableStart = TimeStamp::Now();
if (httpChannelImpl) { if (httpChannelImpl) {
if (httpChannelImpl->IsReadingFromCache()) { if (httpChannelImpl->IsReadingFromCache()) {
transportStatus = NS_NET_STATUS_READING; transportStatus = NS_NET_STATUS_READING;
} }
onDataAvailableStart = httpChannelImpl->GetDataAvailableStartTime();
} }
nsCString data; nsCString data;
@ -1516,7 +1520,7 @@ HttpChannelParent::OnDataAvailable(nsIRequest* aRequest,
if (mIPCClosed || !mBgParent || if (mIPCClosed || !mBgParent ||
!mBgParent->OnTransportAndData(channelStatus, transportStatus, aOffset, !mBgParent->OnTransportAndData(channelStatus, transportStatus, aOffset,
aCount, data)) { aCount, data, onDataAvailableStart)) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }

View file

@ -275,7 +275,8 @@ HttpTransactionChild::OnDataAvailable(nsIRequest* aRequest,
nsHttp::SendFunc<nsCString> sendFunc = nsHttp::SendFunc<nsCString> sendFunc =
[self = UnsafePtr<HttpTransactionChild>(this)]( [self = UnsafePtr<HttpTransactionChild>(this)](
const nsCString& aData, uint64_t aOffset, uint32_t aCount) { const nsCString& aData, uint64_t aOffset, uint32_t aCount) {
return self->SendOnDataAvailable(aData, aOffset, aCount); return self->SendOnDataAvailable(aData, aOffset, aCount,
TimeStamp::Now());
}; };
LOG((" ODA to parent process")); LOG((" ODA to parent process"));
@ -295,8 +296,8 @@ HttpTransactionChild::OnDataAvailable(nsIRequest* aRequest,
[self = UnsafePtr<HttpTransactionChild>(this)]( [self = UnsafePtr<HttpTransactionChild>(this)](
const nsDependentCSubstring& aData, uint64_t aOffset, const nsDependentCSubstring& aData, uint64_t aOffset,
uint32_t aCount) { uint32_t aCount) {
return self->mDataBridgeParent->SendOnTransportAndData(aOffset, aCount, return self->mDataBridgeParent->SendOnTransportAndData(
aData); aOffset, aCount, aData, TimeStamp::Now());
}; };
LOG((" ODA to content process")); LOG((" ODA to content process"));
@ -306,7 +307,7 @@ HttpTransactionChild::OnDataAvailable(nsIRequest* aRequest,
} }
// We still need to send ODA to parent process, because the data needs to be // We still need to send ODA to parent process, because the data needs to be
// saved in cache. Note that we set dataSentToChildProcess to true, to this // saved in cache. Note that we set dataSentToChildProcess to true, so this
// ODA will not be sent to child process. // ODA will not be sent to child process.
RefPtr<HttpTransactionChild> self = this; RefPtr<HttpTransactionChild> self = this;
rv = NS_DispatchToMainThread( rv = NS_DispatchToMainThread(
@ -316,7 +317,8 @@ HttpTransactionChild::OnDataAvailable(nsIRequest* aRequest,
nsHttp::SendFunc<nsCString> sendFunc = nsHttp::SendFunc<nsCString> sendFunc =
[self](const nsCString& aData, uint64_t aOffset, [self](const nsCString& aData, uint64_t aOffset,
uint32_t aCount) { uint32_t aCount) {
return self->SendOnDataAvailable(aData, aOffset, aCount); return self->SendOnDataAvailable(aData, aOffset, aCount,
TimeStamp::Now());
}; };
if (!nsHttp::SendDataInChunks(data, offset, count, sendFunc)) { if (!nsHttp::SendDataInChunks(data, offset, count, sendFunc)) {
@ -485,7 +487,8 @@ HttpTransactionChild::OnStartRequest(nsIRequest* aRequest) {
ToTimingStructArgs(mTransaction->Timings()), proxyConnectResponseCode, ToTimingStructArgs(mTransaction->Timings()), proxyConnectResponseCode,
dataForSniffer, optionalAltSvcUsed, !!mDataBridgeParent, dataForSniffer, optionalAltSvcUsed, !!mDataBridgeParent,
mTransaction->TakeRestartedState(), mTransaction->HTTPSSVCReceivedStage(), mTransaction->TakeRestartedState(), mTransaction->HTTPSSVCReceivedStage(),
mTransaction->GetSupportsHTTP3(), mode, reason, mTransaction->Caps()); mTransaction->GetSupportsHTTP3(), mode, reason, mTransaction->Caps(),
TimeStamp::Now());
return NS_OK; return NS_OK;
} }
@ -523,7 +526,8 @@ HttpTransactionChild::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
MOZ_ASSERT(NS_FAILED(mStatus), "This shoule be only called when failure"); MOZ_ASSERT(NS_FAILED(mStatus), "This shoule be only called when failure");
if (mDataBridgeParent) { if (mDataBridgeParent) {
mDataBridgeParent->OnStopRequest(mStatus, ResourceTimingStructArgs(), mDataBridgeParent->OnStopRequest(mStatus, ResourceTimingStructArgs(),
TimeStamp(), nsHttpHeaderArray()); TimeStamp(), nsHttpHeaderArray(),
TimeStamp::Now());
mDataBridgeParent = nullptr; mDataBridgeParent = nullptr;
} }
}); });
@ -554,7 +558,8 @@ HttpTransactionChild::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
if (mDataBridgeParent) { if (mDataBridgeParent) {
mDataBridgeParent->OnStopRequest( mDataBridgeParent->OnStopRequest(
aStatus, GetTimingAttributes(), lastActTabOpt, aStatus, GetTimingAttributes(), lastActTabOpt,
responseTrailers ? *responseTrailers : nsHttpHeaderArray()); responseTrailers ? *responseTrailers : nsHttpHeaderArray(),
TimeStamp::Now());
mDataBridgeParent = nullptr; mDataBridgeParent = nullptr;
} }
@ -565,7 +570,7 @@ HttpTransactionChild::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
mTransaction->GetTransferSize(), mTransaction->GetTransferSize(),
ToTimingStructArgs(mTransaction->Timings()), ToTimingStructArgs(mTransaction->Timings()),
responseTrailers, mTransactionObserverResult, responseTrailers, mTransactionObserverResult,
lastActTabOpt, infoArgs); lastActTabOpt, infoArgs, TimeStamp::Now());
return NS_OK; return NS_OK;
} }

View file

@ -414,20 +414,21 @@ mozilla::ipc::IPCResult HttpTransactionParent::RecvOnStartRequest(
const bool& aDataToChildProcess, const bool& aRestarted, const bool& aDataToChildProcess, const bool& aRestarted,
const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3, const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3,
const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aTrrSkipReason, const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aTrrSkipReason,
const uint32_t& aCaps) { const uint32_t& aCaps, const TimeStamp& aOnStartRequestStartTime) {
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent( mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
this, this, [self = UnsafePtr<HttpTransactionParent>(this), aStatus,
[self = UnsafePtr<HttpTransactionParent>(this), aStatus, aResponseHead, aResponseHead, securityInfo = nsCOMPtr{aSecurityInfo},
securityInfo = nsCOMPtr{aSecurityInfo}, aProxyConnectFailed, aTimings, aProxyConnectFailed, aTimings, aProxyConnectResponseCode,
aProxyConnectResponseCode, aDataForSniffer = CopyableTArray{std::move(aDataForSniffer)},
aDataForSniffer = CopyableTArray{std::move(aDataForSniffer)}, aAltSvcUsed, aDataToChildProcess, aRestarted,
aAltSvcUsed, aDataToChildProcess, aRestarted, aHTTPSSVCReceivedStage, aHTTPSSVCReceivedStage, aSupportsHttp3, aMode, aTrrSkipReason,
aSupportsHttp3, aMode, aTrrSkipReason, aCaps]() mutable { aCaps, aOnStartRequestStartTime]() mutable {
self->DoOnStartRequest( self->DoOnStartRequest(
aStatus, aResponseHead, securityInfo, aProxyConnectFailed, aTimings, aStatus, aResponseHead, securityInfo, aProxyConnectFailed, aTimings,
aProxyConnectResponseCode, std::move(aDataForSniffer), aAltSvcUsed, aProxyConnectResponseCode, std::move(aDataForSniffer), aAltSvcUsed,
aDataToChildProcess, aRestarted, aHTTPSSVCReceivedStage, aDataToChildProcess, aRestarted, aHTTPSSVCReceivedStage,
aSupportsHttp3, aMode, aTrrSkipReason, aCaps); aSupportsHttp3, aMode, aTrrSkipReason, aCaps,
aOnStartRequestStartTime);
})); }));
return IPC_OK(); return IPC_OK();
} }
@ -459,7 +460,7 @@ void HttpTransactionParent::DoOnStartRequest(
const bool& aDataToChildProcess, const bool& aRestarted, const bool& aDataToChildProcess, const bool& aRestarted,
const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3, const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3,
const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason, const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason,
const uint32_t& aCaps) { const uint32_t& aCaps, const TimeStamp& aOnStartRequestStartTime) {
LOG(("HttpTransactionParent::DoOnStartRequest [this=%p aStatus=%" PRIx32 LOG(("HttpTransactionParent::DoOnStartRequest [this=%p aStatus=%" PRIx32
"]\n", "]\n",
this, static_cast<uint32_t>(aStatus))); this, static_cast<uint32_t>(aStatus)));
@ -478,6 +479,7 @@ void HttpTransactionParent::DoOnStartRequest(
mTRRSkipReason = aSkipReason; mTRRSkipReason = aSkipReason;
mCaps = aCaps; mCaps = aCaps;
mSecurityInfo = aSecurityInfo; mSecurityInfo = aSecurityInfo;
mOnStartRequestStartTime = aOnStartRequestStartTime;
if (aResponseHead.isSome()) { if (aResponseHead.isSome()) {
mResponseHead = MakeUnique<nsHttpResponseHead>(aResponseHead.ref()); mResponseHead = MakeUnique<nsHttpResponseHead>(aResponseHead.ref());
@ -523,7 +525,8 @@ mozilla::ipc::IPCResult HttpTransactionParent::RecvOnTransportStatus(
} }
mozilla::ipc::IPCResult HttpTransactionParent::RecvOnDataAvailable( mozilla::ipc::IPCResult HttpTransactionParent::RecvOnDataAvailable(
const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount) { const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount,
const TimeStamp& aOnDataAvailableStartTime) {
LOG(("HttpTransactionParent::RecvOnDataAvailable [this=%p, aOffset= %" PRIu64 LOG(("HttpTransactionParent::RecvOnDataAvailable [this=%p, aOffset= %" PRIu64
" aCount=%" PRIu32, " aCount=%" PRIu32,
this, aOffset, aCount)); this, aOffset, aCount));
@ -541,14 +544,17 @@ mozilla::ipc::IPCResult HttpTransactionParent::RecvOnDataAvailable(
[self = UnsafePtr<HttpTransactionParent>(this)]() { [self = UnsafePtr<HttpTransactionParent>(this)]() {
return self->GetODATarget(); return self->GetODATarget();
}, },
[self = UnsafePtr<HttpTransactionParent>(this), aData, aOffset, [self = UnsafePtr<HttpTransactionParent>(this), aData, aOffset, aCount,
aCount]() { self->DoOnDataAvailable(aData, aOffset, aCount); })); aOnDataAvailableStartTime]() {
self->DoOnDataAvailable(aData, aOffset, aCount,
aOnDataAvailableStartTime);
}));
return IPC_OK(); return IPC_OK();
} }
void HttpTransactionParent::DoOnDataAvailable(const nsCString& aData, void HttpTransactionParent::DoOnDataAvailable(
const uint64_t& aOffset, const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount,
const uint32_t& aCount) { const TimeStamp& aOnDataAvailableStartTime) {
LOG(("HttpTransactionParent::DoOnDataAvailable [this=%p]\n", this)); LOG(("HttpTransactionParent::DoOnDataAvailable [this=%p]\n", this));
if (mCanceled) { if (mCanceled) {
return; return;
@ -564,6 +570,7 @@ void HttpTransactionParent::DoOnDataAvailable(const nsCString& aData,
return; return;
} }
mOnDataAvailableStartTime = aOnDataAvailableStartTime;
AutoEventEnqueuer ensureSerialDispatch(mEventQ); AutoEventEnqueuer ensureSerialDispatch(mEventQ);
rv = mChannel->OnDataAvailable(this, stringStream, aOffset, aCount); rv = mChannel->OnDataAvailable(this, stringStream, aOffset, aCount);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -597,7 +604,8 @@ mozilla::ipc::IPCResult HttpTransactionParent::RecvOnStopRequest(
const Maybe<nsHttpHeaderArray>& aResponseTrailers, const Maybe<nsHttpHeaderArray>& aResponseTrailers,
Maybe<TransactionObserverResult>&& aTransactionObserverResult, Maybe<TransactionObserverResult>&& aTransactionObserverResult,
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const HttpConnectionInfoCloneArgs& aArgs) { const HttpConnectionInfoCloneArgs& aArgs,
const TimeStamp& aOnStopRequestStartTime) {
LOG(("HttpTransactionParent::RecvOnStopRequest [this=%p status=%" PRIx32 LOG(("HttpTransactionParent::RecvOnStopRequest [this=%p status=%" PRIx32
"]\n", "]\n",
this, static_cast<uint32_t>(aStatus))); this, static_cast<uint32_t>(aStatus)));
@ -613,10 +621,11 @@ mozilla::ipc::IPCResult HttpTransactionParent::RecvOnStopRequest(
this, [self = UnsafePtr<HttpTransactionParent>(this), aStatus, this, [self = UnsafePtr<HttpTransactionParent>(this), aStatus,
aResponseIsComplete, aTransferSize, aTimings, aResponseTrailers, aResponseIsComplete, aTransferSize, aTimings, aResponseTrailers,
aTransactionObserverResult{std::move(aTransactionObserverResult)}, aTransactionObserverResult{std::move(aTransactionObserverResult)},
cinfo{std::move(cinfo)}]() mutable { cinfo{std::move(cinfo)}, aOnStopRequestStartTime]() mutable {
self->DoOnStopRequest(aStatus, aResponseIsComplete, aTransferSize, self->DoOnStopRequest(aStatus, aResponseIsComplete, aTransferSize,
aTimings, aResponseTrailers, aTimings, aResponseTrailers,
std::move(aTransactionObserverResult), cinfo); std::move(aTransactionObserverResult), cinfo,
aOnStopRequestStartTime);
})); }));
return IPC_OK(); return IPC_OK();
} }
@ -626,7 +635,7 @@ void HttpTransactionParent::DoOnStopRequest(
const int64_t& aTransferSize, const TimingStructArgs& aTimings, const int64_t& aTransferSize, const TimingStructArgs& aTimings,
const Maybe<nsHttpHeaderArray>& aResponseTrailers, const Maybe<nsHttpHeaderArray>& aResponseTrailers,
Maybe<TransactionObserverResult>&& aTransactionObserverResult, Maybe<TransactionObserverResult>&& aTransactionObserverResult,
nsHttpConnectionInfo* aConnInfo) { nsHttpConnectionInfo* aConnInfo, const TimeStamp& aOnStopRequestStartTime) {
LOG(("HttpTransactionParent::DoOnStopRequest [this=%p]\n", this)); LOG(("HttpTransactionParent::DoOnStopRequest [this=%p]\n", this));
if (mCanceled) { if (mCanceled) {
return; return;
@ -640,6 +649,7 @@ void HttpTransactionParent::DoOnStopRequest(
mResponseIsComplete = aResponseIsComplete; mResponseIsComplete = aResponseIsComplete;
mTransferSize = aTransferSize; mTransferSize = aTransferSize;
mOnStopRequestStartTime = aOnStopRequestStartTime;
TimingStructArgsToTimingsStruct(aTimings, mTimings); TimingStructArgsToTimingsStruct(aTimings, mTimings);

View file

@ -56,21 +56,22 @@ class HttpTransactionParent final : public PHttpTransactionParent,
const bool& aDataToChildProcess, const bool& aRestarted, const bool& aDataToChildProcess, const bool& aRestarted,
const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3, const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3,
const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason, const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason,
const uint32_t& aCaps); const uint32_t& aCaps, const TimeStamp& aOnStartRequestStartTime);
mozilla::ipc::IPCResult RecvOnTransportStatus( mozilla::ipc::IPCResult RecvOnTransportStatus(
const nsresult& aStatus, const int64_t& aProgress, const nsresult& aStatus, const int64_t& aProgress,
const int64_t& aProgressMax, const int64_t& aProgressMax,
Maybe<NetworkAddressArg>&& aNetworkAddressArg); Maybe<NetworkAddressArg>&& aNetworkAddressArg);
mozilla::ipc::IPCResult RecvOnDataAvailable(const nsCString& aData, mozilla::ipc::IPCResult RecvOnDataAvailable(
const uint64_t& aOffset, const nsCString& aData, const uint64_t& aOffset, const uint32_t& aCount,
const uint32_t& aCount); const TimeStamp& aOnDataAvailableStartTime);
mozilla::ipc::IPCResult RecvOnStopRequest( mozilla::ipc::IPCResult RecvOnStopRequest(
const nsresult& aStatus, const bool& aResponseIsComplete, const nsresult& aStatus, const bool& aResponseIsComplete,
const int64_t& aTransferSize, const TimingStructArgs& aTimings, const int64_t& aTransferSize, const TimingStructArgs& aTimings,
const Maybe<nsHttpHeaderArray>& responseTrailers, const Maybe<nsHttpHeaderArray>& responseTrailers,
Maybe<TransactionObserverResult>&& aTransactionObserverResult, Maybe<TransactionObserverResult>&& aTransactionObserverResult,
const TimeStamp& aLastActiveTabOptHit, const TimeStamp& aLastActiveTabOptHit,
const HttpConnectionInfoCloneArgs& aArgs); const HttpConnectionInfoCloneArgs& aArgs,
const TimeStamp& aOnStopRequestStartTime);
mozilla::ipc::IPCResult RecvOnInitFailed(const nsresult& aStatus); mozilla::ipc::IPCResult RecvOnInitFailed(const nsresult& aStatus);
mozilla::ipc::IPCResult RecvOnH2PushStream(const uint32_t& aPushedStreamId, mozilla::ipc::IPCResult RecvOnH2PushStream(const uint32_t& aPushedStreamId,
@ -93,6 +94,16 @@ class HttpTransactionParent final : public PHttpTransactionParent,
mRedirectEnd = aRedirectEnd; mRedirectEnd = aRedirectEnd;
} }
virtual TimeStamp GetOnStartRequestStartTime() const override {
return mOnStartRequestStartTime;
}
virtual TimeStamp GetDataAvailableStartTime() const override {
return mOnDataAvailableStartTime;
}
virtual TimeStamp GetOnStopRequestStartTime() const override {
return mOnStopRequestStartTime;
}
private: private:
virtual ~HttpTransactionParent(); virtual ~HttpTransactionParent();
@ -107,15 +118,17 @@ class HttpTransactionParent final : public PHttpTransactionParent,
const bool& aDataToChildProcess, const bool& aRestarted, const bool& aDataToChildProcess, const bool& aRestarted,
const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3, const uint32_t& aHTTPSSVCReceivedStage, const bool& aSupportsHttp3,
const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason, const nsIRequest::TRRMode& aMode, const TRRSkippedReason& aSkipReason,
const uint32_t& aCaps); const uint32_t& aCaps, const TimeStamp& aOnStartRequestStartTime);
void DoOnDataAvailable(const nsCString& aData, const uint64_t& aOffset, void DoOnDataAvailable(const nsCString& aData, const uint64_t& aOffset,
const uint32_t& aCount); const uint32_t& aCount,
const TimeStamp& aOnDataAvailableStartTime);
void DoOnStopRequest( void DoOnStopRequest(
const nsresult& aStatus, const bool& aResponseIsComplete, const nsresult& aStatus, const bool& aResponseIsComplete,
const int64_t& aTransferSize, const TimingStructArgs& aTimings, const int64_t& aTransferSize, const TimingStructArgs& aTimings,
const Maybe<nsHttpHeaderArray>& responseTrailers, const Maybe<nsHttpHeaderArray>& responseTrailers,
Maybe<TransactionObserverResult>&& aTransactionObserverResult, Maybe<TransactionObserverResult>&& aTransactionObserverResult,
nsHttpConnectionInfo* aConnInfo); nsHttpConnectionInfo* aConnInfo,
const TimeStamp& aOnStopRequestStartTime);
void DoNotifyListener(); void DoNotifyListener();
void ContinueDoNotifyListener(); void ContinueDoNotifyListener();
// Get event target for ODA. // Get event target for ODA.
@ -164,6 +177,9 @@ class HttpTransactionParent final : public PHttpTransactionParent,
TimingStruct mTimings; TimingStruct mTimings;
TimeStamp mDomainLookupStart; TimeStamp mDomainLookupStart;
TimeStamp mDomainLookupEnd; TimeStamp mDomainLookupEnd;
TimeStamp mOnStartRequestStartTime;
TimeStamp mOnDataAvailableStartTime;
TimeStamp mOnStopRequestStartTime;
TransactionObserverFunc mTransactionObserver; TransactionObserverFunc mTransactionObserver;
OnPushCallback mOnPushCallback; OnPushCallback mOnPushCallback;
nsTArray<uint8_t> mDataForSniffer; nsTArray<uint8_t> mDataForSniffer;

View file

@ -169,6 +169,10 @@ class HttpTransactionShell : public nsISupports {
virtual bool GetSupportsHTTP3() = 0; virtual bool GetSupportsHTTP3() = 0;
virtual void SetIsForWebTransport(bool aIsForWebTransport) = 0; virtual void SetIsForWebTransport(bool aIsForWebTransport) = 0;
virtual TimeStamp GetOnStartRequestStartTime() const { return TimeStamp(); }
virtual TimeStamp GetDataAvailableStartTime() const { return TimeStamp(); }
virtual TimeStamp GetOnStopRequestStartTime() const { return TimeStamp(); }
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(HttpTransactionShell, HTTPTRANSACTIONSHELL_IID) NS_DEFINE_STATIC_IID_ACCESSOR(HttpTransactionShell, HTTPTRANSACTIONSHELL_IID)

View file

@ -14,12 +14,14 @@ async protocol PBackgroundDataBridge
child: child:
async OnTransportAndData(uint64_t offset, async OnTransportAndData(uint64_t offset,
uint32_t count, uint32_t count,
nsCString data); nsCString data,
TimeStamp onDataAvailableStart);
async OnStopRequest(nsresult aStatus, async OnStopRequest(nsresult aStatus,
ResourceTimingStructArgs timing, ResourceTimingStructArgs timing,
TimeStamp lastActiveTabOptimization, TimeStamp lastActiveTabOptimization,
nsHttpHeaderArray responseTrailers); nsHttpHeaderArray responseTrailers,
TimeStamp onStopRequestStart);
both: both:
async __delete__(); async __delete__();

View file

@ -26,7 +26,8 @@ child:
bool useResponseHead, bool useResponseHead,
nsHttpHeaderArray requestHeaders, nsHttpHeaderArray requestHeaders,
HttpChannelOnStartRequestArgs args, HttpChannelOnStartRequestArgs args,
HttpChannelAltDataStream altData); HttpChannelAltDataStream altData,
TimeStamp onStartRequestStart);
// Combines a single OnDataAvailable and its associated OnProgress & // Combines a single OnDataAvailable and its associated OnProgress &
// OnStatus calls into one IPDL message // OnStatus calls into one IPDL message
@ -35,7 +36,8 @@ child:
uint64_t offset, uint64_t offset,
uint32_t count, uint32_t count,
nsCString data, nsCString data,
bool dataFromSocketProcess); bool dataFromSocketProcess,
TimeStamp onDataAvailableStart);
async OnStopRequest(nsresult channelStatus, async OnStopRequest(nsresult channelStatus,
@ -43,7 +45,8 @@ child:
TimeStamp lastActiveTabOptimization, TimeStamp lastActiveTabOptimization,
nsHttpHeaderArray responseTrailers, nsHttpHeaderArray responseTrailers,
ConsoleReportCollected[] consoleReport, ConsoleReportCollected[] consoleReport,
bool fromSocketProcess); bool fromSocketProcess,
TimeStamp onStopRequestStart);
async OnConsoleReport(ConsoleReportCollected[] consoleReport); async OnConsoleReport(ConsoleReportCollected[] consoleReport);

View file

@ -59,14 +59,16 @@ parent:
bool supportsHttp3, bool supportsHttp3,
TRRMode trrMode, TRRMode trrMode,
TRRSkippedReason trrSkipReason, TRRSkippedReason trrSkipReason,
uint32_t caps); uint32_t caps,
TimeStamp onStartRequestStart);
async OnTransportStatus(nsresult status, async OnTransportStatus(nsresult status,
int64_t progress, int64_t progress,
int64_t progressMax, int64_t progressMax,
NetworkAddressArg? networkAddressArg); NetworkAddressArg? networkAddressArg);
async OnDataAvailable(nsCString data, async OnDataAvailable(nsCString data,
uint64_t offset, uint64_t offset,
uint32_t count); uint32_t count,
TimeStamp onDataAvailableStart);
async OnStopRequest(nsresult status, async OnStopRequest(nsresult status,
bool responseIsComplete, bool responseIsComplete,
int64_t transferSize, int64_t transferSize,
@ -74,7 +76,8 @@ parent:
nsHttpHeaderArray? responseTrailers, nsHttpHeaderArray? responseTrailers,
TransactionObserverResult? transactionObserverResult, TransactionObserverResult? transactionObserverResult,
TimeStamp lastActiveTabOptimization, TimeStamp lastActiveTabOptimization,
HttpConnectionInfoCloneArgs connInfoArgs); HttpConnectionInfoCloneArgs connInfoArgs,
TimeStamp onStopRequestStart);
async OnInitFailed(nsresult status); async OnInitFailed(nsresult status);
async OnH2PushStream(uint32_t pushedStreamId, async OnH2PushStream(uint32_t pushedStreamId,
nsCString resourceUrl, nsCString resourceUrl,

View file

@ -62,6 +62,7 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/BasePrincipal.h" #include "mozilla/BasePrincipal.h"
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
#include "mozilla/PerfStats.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/ProfilerLabels.h" #include "mozilla/ProfilerLabels.h"
#include "mozilla/Components.h" #include "mozilla/Components.h"
@ -7117,16 +7118,15 @@ nsHttpChannel::GetRequestMethod(nsACString& aMethod) {
// nsHttpChannel::nsIRequestObserver // nsHttpChannel::nsIRequestObserver
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void RecordOnStartTelemetry(nsresult aStatus, void nsHttpChannel::RecordOnStartTelemetry(nsresult aStatus,
HttpTransactionShell* aTransaction, bool aIsNavigation) {
bool aIsNavigation) {
Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_ONSTART_SUCCESS, Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_ONSTART_SUCCESS,
NS_SUCCEEDED(aStatus)); NS_SUCCEEDED(aStatus));
if (aTransaction) { if (mTransaction) {
Telemetry::Accumulate( Telemetry::Accumulate(
Telemetry::HTTP3_CHANNEL_ONSTART_SUCCESS, Telemetry::HTTP3_CHANNEL_ONSTART_SUCCESS,
(aTransaction->IsHttp3Used()) ? "http3"_ns : "no_http3"_ns, (mTransaction->IsHttp3Used()) ? "http3"_ns : "no_http3"_ns,
NS_SUCCEEDED(aStatus)); NS_SUCCEEDED(aStatus));
} }
@ -7157,6 +7157,24 @@ static void RecordOnStartTelemetry(nsresult aStatus,
static_cast<uint32_t>(state)); static_cast<uint32_t>(state));
} }
} }
if (nsIOService::UseSocketProcess() && mTransaction) {
const TimeStamp now = TimeStamp::Now();
TimeStamp responseEnd = mTransaction->GetResponseEnd();
if (!responseEnd.IsNull()) {
PerfStats::RecordMeasurement(PerfStats::Metric::ResponseEndSocketToParent,
now - responseEnd);
}
mOnStartRequestStartTime = mTransaction->GetOnStartRequestStartTime();
if (!mOnStartRequestStartTime.IsNull()) {
PerfStats::RecordMeasurement(
PerfStats::Metric::OnStartRequestSocketToParent,
now - mOnStartRequestStartTime);
}
} else {
mOnStartRequestStartTime = TimeStamp::Now();
}
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -7191,7 +7209,7 @@ nsHttpChannel::OnStartRequest(nsIRequest* request) {
"]\n", "]\n",
this, request, static_cast<uint32_t>(static_cast<nsresult>(mStatus)))); this, request, static_cast<uint32_t>(static_cast<nsresult>(mStatus))));
RecordOnStartTelemetry(mStatus, mTransaction, IsNavigation()); RecordOnStartTelemetry(mStatus, IsNavigation());
if (mRaceCacheWithNetwork) { if (mRaceCacheWithNetwork) {
LOG( LOG(
@ -7734,6 +7752,17 @@ nsHttpChannel::OnStopRequest(nsIRequest* request, nsresult status) {
mResponseTrailers = mTransaction->TakeResponseTrailers(); mResponseTrailers = mTransaction->TakeResponseTrailers();
if (nsIOService::UseSocketProcess() && mTransaction) {
mOnStopRequestStartTime = mTransaction->GetOnStopRequestStartTime();
if (!mOnStopRequestStartTime.IsNull()) {
PerfStats::RecordMeasurement(
PerfStats::Metric::OnStopRequestSocketToParent,
TimeStamp::Now() - mOnStopRequestStartTime);
}
} else {
mOnStopRequestStartTime = TimeStamp::Now();
}
// at this point, we're done with the transaction // at this point, we're done with the transaction
mTransactionTimings = mTransaction->Timings(); mTransactionTimings = mTransaction->Timings();
mTransaction = nullptr; mTransaction = nullptr;
@ -8258,6 +8287,16 @@ nsHttpChannel::OnDataAvailable(nsIRequest* request, nsIInputStream* input,
seekable = nullptr; seekable = nullptr;
} }
if (nsIOService::UseSocketProcess() && mTransaction) {
mOnDataAvailableStartTime = mTransaction->GetDataAvailableStartTime();
if (!mOnDataAvailableStartTime.IsNull()) {
PerfStats::RecordMeasurement(
PerfStats::Metric::OnDataAvailableSocketToParent,
TimeStamp::Now() - mOnDataAvailableStartTime);
}
} else {
mOnDataAvailableStartTime = TimeStamp::Now();
}
nsresult rv = nsresult rv =
mListener->OnDataAvailable(this, input, mLogicalOffset, count); mListener->OnDataAvailable(this, input, mLogicalOffset, count);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {

View file

@ -802,6 +802,8 @@ class nsHttpChannel final : public HttpBaseChannel,
void SetHTTPSSVCRecord(already_AddRefed<nsIDNSHTTPSSVCRecord>&& aRecord); void SetHTTPSSVCRecord(already_AddRefed<nsIDNSHTTPSSVCRecord>&& aRecord);
void RecordOnStartTelemetry(nsresult aStatus, bool aIsNavigation);
// Timer used to delay the network request, or to trigger the network // Timer used to delay the network request, or to trigger the network
// request if retrieving the cache entry takes too long. // request if retrieving the cache entry takes too long.
nsCOMPtr<nsITimer> mNetworkTriggerTimer; nsCOMPtr<nsITimer> mNetworkTriggerTimer;

View file

@ -47,6 +47,13 @@
MACRO(HttpChannelAsyncOpenToTransactionPending) \ MACRO(HttpChannelAsyncOpenToTransactionPending) \
MACRO(HttpChannelResponseStartParentToContent) \ MACRO(HttpChannelResponseStartParentToContent) \
MACRO(HttpChannelResponseEndParentToContent) \ MACRO(HttpChannelResponseEndParentToContent) \
MACRO(ResponseEndSocketToParent) \
MACRO(OnStartRequestSocketToParent) \
MACRO(OnDataAvailableSocketToParent) \
MACRO(OnStopRequestSocketToParent) \
MACRO(OnStartRequestToContent) \
MACRO(OnDataAvailableToContent) \
MACRO(OnStopRequestToContent) \
MACRO(JSBC_Compression) \ MACRO(JSBC_Compression) \
MACRO(JSBC_Decompression) \ MACRO(JSBC_Decompression) \
MACRO(JSBC_IO_Read) \ MACRO(JSBC_IO_Read) \