From 4e13d0a06a28c81e8afd72e985adfd9e91d79d9e Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Thu, 28 Mar 2013 18:38:04 +0100 Subject: [PATCH] Bug 729182 - Implement visual event tracer, part1 - instrumentation, r=mcmanus,bz,ehsan,bsmedberg,michal --- docshell/base/nsDocShell.cpp | 10 +++++ netwerk/base/src/nsSocketTransport2.cpp | 8 ++++ netwerk/cache/nsCacheEntry.cpp | 3 ++ netwerk/cache/nsCacheService.cpp | 45 ++++++++++++++++++- netwerk/cache/nsDiskCacheMap.cpp | 13 ++++++ netwerk/cache/nsDiskCacheStreams.cpp | 14 +++++- netwerk/dns/nsDNSService2.cpp | 6 +++ netwerk/dns/nsHostResolver.cpp | 9 ++++ netwerk/protocol/http/nsHttpChannel.cpp | 29 ++++++++++++ netwerk/protocol/http/nsHttpConnectionMgr.cpp | 1 + netwerk/protocol/http/nsHttpTransaction.cpp | 26 +++++++++++ 11 files changed, 161 insertions(+), 3 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 4e07e7e25374..24d1b64198be 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -82,6 +82,7 @@ #include "mozilla/Telemetry.h" #include "mozilla/AutoRestore.h" #include "mozilla/Attributes.h" +#include "mozilla/VisualEventTracer.h" // we want to explore making the document own the load group // so we can associate the document URI with the load group. @@ -6666,6 +6667,8 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress, if(!aChannel) return NS_ERROR_NULL_POINTER; + MOZ_EVENT_TRACER_DONE(this, "docshell::pageload"); + nsCOMPtr url; nsresult rv = aChannel->GetURI(getter_AddRefs(url)); if (NS_FAILED(rv)) return rv; @@ -9389,6 +9392,13 @@ nsDocShell::DoURILoad(nsIURI * aURI, bool aBypassClassifier, bool aForceAllowCookies) { +#ifdef MOZ_VISUAL_EVENT_TRACER + nsAutoCString urlSpec; + aURI->GetAsciiSpec(urlSpec); + MOZ_EVENT_TRACER_NAME_OBJECT(this, urlSpec.BeginReading()); + MOZ_EVENT_TRACER_EXEC(this, "docshell::pageload"); +#endif + nsresult rv; nsCOMPtr uriLoader; diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index 8054a7b691f9..605f3606cd96 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -24,6 +24,7 @@ #include "prnetdb.h" #include "prerr.h" #include "NetworkActivityMonitor.h" +#include "mozilla/VisualEventTracer.h" #include "nsIServiceManager.h" #include "nsISocketProviderService.h" @@ -729,6 +730,8 @@ nsSocketTransport::Init(const char **types, uint32_t typeCount, const nsACString &host, uint16_t port, nsIProxyInfo *givenProxyInfo) { + MOZ_EVENT_TRACER_NAME_OBJECT(this, host.BeginReading()); + nsCOMPtr proxyInfo; if (givenProxyInfo) { proxyInfo = do_QueryInterface(givenProxyInfo); @@ -1179,6 +1182,8 @@ nsSocketTransport::InitiateSocket() // PRNetAddr prAddr; NetAddrToPRNetAddr(&mNetAddr, &prAddr); + + MOZ_EVENT_TRACER_EXEC(this, "net::tcp::connect"); status = PR_Connect(fd, &prAddr, NS_SOCKET_CONNECT_TIMEOUT); if (status == PR_SUCCESS) { // @@ -1404,6 +1409,8 @@ nsSocketTransport::OnSocketConnected() mFDconnected = true; } + MOZ_EVENT_TRACER_DONE(this, "net::tcp::connect"); + SendStatus(NS_NET_STATUS_CONNECTED_TO); } @@ -2144,6 +2151,7 @@ nsSocketTransport::OnLookupComplete(nsICancelable *request, // flag host lookup complete for the benefit of the ResolveHost method. mResolving = false; + MOZ_EVENT_TRACER_WAIT(this, "net::tcp::connect"); nsresult rv = PostEvent(MSG_DNS_LOOKUP_COMPLETE, status, rec); // if posting a message fails, then we should assume that the socket diff --git a/netwerk/cache/nsCacheEntry.cpp b/netwerk/cache/nsCacheEntry.cpp index 3e1494c98eb2..42f964de39ae 100644 --- a/netwerk/cache/nsCacheEntry.cpp +++ b/netwerk/cache/nsCacheEntry.cpp @@ -17,6 +17,7 @@ #include "nsCacheService.h" #include "nsCacheDevice.h" #include "nsHashKeys.h" +#include "mozilla/VisualEventTracer.h" using namespace mozilla; @@ -44,6 +45,8 @@ nsCacheEntry::nsCacheEntry(const nsACString & key, SetStoragePolicy(storagePolicy); MarkPublic(); + + MOZ_EVENT_TRACER_NAME_OBJECT(this, key.BeginReading()); } diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp index 657085ee1616..d5f518531457 100644 --- a/netwerk/cache/nsCacheService.cpp +++ b/netwerk/cache/nsCacheService.cpp @@ -37,8 +37,8 @@ #include "mozilla/Services.h" #include "nsITimer.h" - #include "mozilla/net/NeckoCommon.h" +#include "mozilla/VisualEventTracer.h" #include using namespace mozilla; @@ -971,6 +971,8 @@ class nsProcessRequestEvent : public nsRunnable { public: nsProcessRequestEvent(nsCacheRequest *aRequest) { + MOZ_EVENT_TRACER_NAME_OBJECT(aRequest, aRequest->mKey.get()); + MOZ_EVENT_TRACER_WAIT(aRequest, "net::cache::ProcessRequest"); mRequest = aRequest; } @@ -1131,6 +1133,8 @@ nsCacheService::Init() CACHE_LOG_INIT(); + MOZ_EVENT_TRACER_NAME_OBJECT(nsCacheService::gService, "nsCacheService"); + nsresult rv = NS_NewNamedThread("Cache I/O", getter_AddRefs(mCacheIOThread)); if (NS_FAILED(rv)) { @@ -1800,6 +1804,12 @@ public: NS_IMETHOD Run() { + mozilla::eventtracer::AutoEventTracer tracer( + static_cast(this), + eventtracer::eExec, + eventtracer::eDone, + "net::cache::OnCacheEntryAvailable"); + mListener->OnCacheEntryAvailable(mDescriptor, mAccessGranted, mStatus); NS_RELEASE(mListener); @@ -1841,6 +1851,8 @@ nsCacheService::NotifyListener(nsCacheRequest * request, return NS_ERROR_OUT_OF_MEMORY; } + MOZ_EVENT_TRACER_NAME_OBJECT(ev.get(), request->mKey.get()); + MOZ_EVENT_TRACER_WAIT(ev.get(), "net::cache::OnCacheEntryAvailable"); return request->mThread->Dispatch(ev, NS_DISPATCH_NORMAL); } @@ -1850,6 +1862,12 @@ nsCacheService::ProcessRequest(nsCacheRequest * request, bool calledFromOpenCacheEntry, nsICacheEntryDescriptor ** result) { + mozilla::eventtracer::AutoEventTracer tracer( + request, + eventtracer::eExec, + eventtracer::eDone, + "net::cache::ProcessRequest"); + // !!! must be called with mLock held !!! nsresult rv; nsCacheEntry * entry = nullptr; @@ -2011,6 +2029,12 @@ nsCacheService::ActivateEntry(nsCacheRequest * request, if (!mInitialized || mClearingEntries) return NS_ERROR_NOT_AVAILABLE; + mozilla::eventtracer::AutoEventTracer tracer( + request, + eventtracer::eExec, + eventtracer::eDone, + "net::cache::ActivateEntry"); + nsresult rv = NS_OK; NS_ASSERTION(request != nullptr, "ActivateEntry called with no request"); @@ -2112,6 +2136,13 @@ nsCacheService::SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy, Telemetry::AutoTimer timer; nsCacheEntry * entry = nullptr; + MOZ_EVENT_TRACER_NAME_OBJECT(key, key->BeginReading()); + eventtracer::AutoEventTracer searchCacheDevices( + key, + eventtracer::eExec, + eventtracer::eDone, + "net::cache::SearchCacheDevices"); + CACHE_LOG_DEBUG(("mMemoryDevice: 0x%p\n", mMemoryDevice)); *collision = false; @@ -2569,13 +2600,15 @@ nsCacheService::Lock(mozilla::Telemetry::ID mainThreadLockerID) } else { lockerID = mozilla::Telemetry::HistogramCount; generalID = mozilla::Telemetry::CACHE_SERVICE_LOCK_WAIT_2; - } + } TimeStamp start(TimeStamp::Now()); + MOZ_EVENT_TRACER_WAIT(nsCacheService::gService, "net::cache::lock"); gService->mLock.Lock(); TimeStamp stop(TimeStamp::Now()); + MOZ_EVENT_TRACER_EXEC(nsCacheService::gService, "net::cache::lock"); // Telemetry isn't thread safe on its own, but this is OK because we're // protecting it with the cache lock. @@ -2595,6 +2628,8 @@ nsCacheService::Unlock() gService->mLock.Unlock(); + MOZ_EVENT_TRACER_DONE(nsCacheService::gService, "net::cache::lock"); + for (uint32_t i = 0; i < doomed.Length(); ++i) doomed[i]->Release(); } @@ -2700,6 +2735,12 @@ nsCacheService::DeactivateEntry(nsCacheEntry * entry) nsresult nsCacheService::ProcessPendingRequests(nsCacheEntry * entry) { + mozilla::eventtracer::AutoEventTracer tracer( + entry, + eventtracer::eExec, + eventtracer::eDone, + "net::cache::ProcessPendingRequests"); + nsresult rv = NS_OK; nsCacheRequest * request = (nsCacheRequest *)PR_LIST_HEAD(&entry->mRequestQ); nsCacheRequest * nextRequest; diff --git a/netwerk/cache/nsDiskCacheMap.cpp b/netwerk/cache/nsDiskCacheMap.cpp index 642470faef02..c747b72ce8fb 100644 --- a/netwerk/cache/nsDiskCacheMap.cpp +++ b/netwerk/cache/nsDiskCacheMap.cpp @@ -18,6 +18,7 @@ #include "nsSerializationHelper.h" #include "mozilla/Telemetry.h" +#include "mozilla/VisualEventTracer.h" #include using namespace mozilla; @@ -889,6 +890,12 @@ nsDiskCacheMap::WriteDiskCacheEntry(nsDiskCacheBinding * binding) CACHE_LOG_DEBUG(("CACHE: WriteDiskCacheEntry [%x]\n", binding->mRecord.HashNumber())); + mozilla::eventtracer::AutoEventTracer writeDiskCacheEntry( + binding->mCacheEntry, + mozilla::eventtracer::eExec, + mozilla::eventtracer::eDone, + "net::cache::WriteDiskCacheEntry"); + nsresult rv = NS_OK; uint32_t size; nsDiskCacheEntry * diskEntry = CreateDiskCacheEntry(binding, &size); @@ -1013,6 +1020,12 @@ nsDiskCacheMap::WriteDataCacheBlocks(nsDiskCacheBinding * binding, char * buffer CACHE_LOG_DEBUG(("CACHE: WriteDataCacheBlocks [%x size=%u]\n", binding->mRecord.HashNumber(), size)); + mozilla::eventtracer::AutoEventTracer writeDataCacheBlocks( + binding->mCacheEntry, + mozilla::eventtracer::eExec, + mozilla::eventtracer::eDone, + "net::cache::WriteDataCacheBlocks"); + nsresult rv = NS_OK; // determine block file & number of blocks diff --git a/netwerk/cache/nsDiskCacheStreams.cpp b/netwerk/cache/nsDiskCacheStreams.cpp index a77bb4c32646..80c9cd48082f 100644 --- a/netwerk/cache/nsDiskCacheStreams.cpp +++ b/netwerk/cache/nsDiskCacheStreams.cpp @@ -15,7 +15,7 @@ #include "mozilla/Telemetry.h" #include "mozilla/TimeStamp.h" #include - +#include "mozilla/VisualEventTracer.h" // we pick 16k as the max buffer size because that is the threshold above which // we are unable to store the data in the cache block files @@ -535,6 +535,12 @@ nsDiskCacheStreamIO::OpenCacheFile(int flags, PRFileDesc ** fd) nsresult nsDiskCacheStreamIO::ReadCacheBlocks(uint32_t bufferSize) { + mozilla::eventtracer::AutoEventTracer readCacheBlocks( + mBinding->mCacheEntry, + mozilla::eventtracer::eExec, + mozilla::eventtracer::eDone, + "net::cache::ReadCacheBlocks"); + NS_ASSERTION(mStreamEnd == mBinding->mCacheEntry->DataSize(), "bad stream"); NS_ASSERTION(bufferSize <= kMaxBufferSize, "bufferSize too large for buffer"); NS_ASSERTION(mStreamEnd <= bufferSize, "data too large for buffer"); @@ -558,6 +564,12 @@ nsDiskCacheStreamIO::ReadCacheBlocks(uint32_t bufferSize) nsresult nsDiskCacheStreamIO::FlushBufferToFile() { + mozilla::eventtracer::AutoEventTracer flushBufferToFile( + mBinding->mCacheEntry, + mozilla::eventtracer::eExec, + mozilla::eventtracer::eDone, + "net::cache::FlushBufferToFile"); + nsresult rv; nsDiskCacheRecord * record = &mBinding->mRecord; diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index f85bafc8303b..93afd604de75 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -30,6 +30,7 @@ #include "nsProxyRelease.h" #include "mozilla/Attributes.h" +#include "mozilla/VisualEventTracer.h" using namespace mozilla; using namespace mozilla::net; @@ -285,6 +286,8 @@ nsDNSAsyncRequest::OnLookupComplete(nsHostResolver *resolver, status = NS_ERROR_OUT_OF_MEMORY; } + MOZ_EVENT_TRACER_DONE(this, "net::dns::lookup"); + mListener->OnLookupComplete(this, rec, status); mListener = nullptr; @@ -629,6 +632,9 @@ nsDNSService::AsyncResolve(const nsACString &hostname, return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*result = req); + MOZ_EVENT_TRACER_NAME_OBJECT(req, hostname.BeginReading()); + MOZ_EVENT_TRACER_WAIT(req, "net::dns::lookup"); + // addref for resolver; will be released when OnLookupComplete is called. NS_ADDREF(req); rv = res->ResolveHost(req->mHost.get(), flags, af, req); diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index f917846bde2e..9da34062b686 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -36,6 +36,7 @@ #include "mozilla/HashFunctions.h" #include "mozilla/TimeStamp.h" #include "mozilla/Telemetry.h" +#include "mozilla/VisualEventTracer.h" using namespace mozilla; using namespace mozilla::net; @@ -169,6 +170,9 @@ nsHostRecord::Create(const nsHostKey *key, nsHostRecord **result) void *place = ::operator new(size); *result = new(place) nsHostRecord(key); NS_ADDREF(*result); + + MOZ_EVENT_TRACER_NAME_OBJECT(*result, key->host); + return NS_OK; } @@ -712,6 +716,8 @@ nsHostResolver::ConditionallyCreateThread(nsHostRecord *rec) nsresult nsHostResolver::IssueLookup(nsHostRecord *rec) { + MOZ_EVENT_TRACER_WAIT(rec, "net::dns::resolve"); + nsresult rv = NS_OK; NS_ASSERTION(!rec->resolving, "record is already being resolved"); @@ -890,6 +896,8 @@ nsHostResolver::OnLookupComplete(nsHostRecord *rec, nsresult status, AddrInfo *r } } + MOZ_EVENT_TRACER_DONE(rec, "net::dns::resolve"); + if (!PR_CLIST_IS_EMPTY(&cbs)) { PRCList *node = cbs.next; while (node != &cbs) { @@ -970,6 +978,7 @@ nsHostResolver::ThreadFunc(void *arg) flags |= PR_AI_NOCANONNAME; TimeStamp startTime = TimeStamp::Now(); + MOZ_EVENT_TRACER_EXEC(rec, "net::dns::resolve"); // We need to remove IPv4 records manually // because PR_GetAddrInfoByName doesn't support PR_AF_INET6. diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index f95f28fa5691..41eefd3d405c 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -34,6 +34,7 @@ #include "base/compiler_specific.h" #include "NullHttpTransaction.h" #include "mozilla/Attributes.h" +#include "mozilla/VisualEventTracer.h" namespace mozilla { namespace net { @@ -161,9 +162,13 @@ AutoRedirectVetoNotifier::ReportRedirectResult(bool succeeded) NS_QueryNotificationCallbacks(mChannel, NS_GET_IID(nsIRedirectResultListener), getter_AddRefs(vetoHook)); + + nsHttpChannel * channel = mChannel; mChannel = nullptr; if (vetoHook) vetoHook->OnRedirectResult(succeeded); + + MOZ_EVENT_TRACER_DONE(channel, "net::http::redirect-callbacks"); } class HttpCacheQuery : public nsRunnable, public nsICacheListener @@ -320,6 +325,12 @@ nsHttpChannel::Init(nsIURI *uri, uint32_t proxyResolveFlags, nsIURI *proxyURI) { +#ifdef MOZ_VISUAL_EVENT_TRACER + nsAutoCString url; + uri->GetAsciiSpec(url); + MOZ_EVENT_TRACER_NAME_OBJECT(this, url.get()); +#endif + nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI); if (NS_FAILED(rv)) @@ -2332,6 +2343,8 @@ IsSubRangeRequest(nsHttpRequestHead &aRequestHead) nsresult nsHttpChannel::OpenCacheEntry(bool usingSSL) { + MOZ_EVENT_TRACER_EXEC(this, "net::http::OpenCacheEntry"); + nsresult rv; NS_ASSERTION(!mOnCacheEntryAvailableCallback, "Unexpected state"); @@ -3981,6 +3994,11 @@ nsHttpChannel::AsyncProcessRedirection(uint32_t redirectType) LOG(("nsHttpChannel::AsyncProcessRedirection [this=%p type=%u]\n", this, redirectType)); + // The channel is actually starting its operation now, at least because + // we want it to appear like being in the waiting phase until now. + MOZ_EVENT_TRACER_EXEC(this, "net::http::channel"); + MOZ_EVENT_TRACER_EXEC(this, "net::http::redirect-callbacks"); + const char *location = mResponseHead->PeekHeader(nsHttp::Location); // if a location header was not given, then we can't perform the redirect, @@ -4334,6 +4352,8 @@ nsHttpChannel::GetSecurityInfo(nsISupports **securityInfo) NS_IMETHODIMP nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context) { + MOZ_EVENT_TRACER_WAIT(this, "net::http::channel"); + LOG(("nsHttpChannel::AsyncOpen [this=%p]\n", this)); NS_ENSURE_ARG_POINTER(listener); @@ -5069,6 +5089,8 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st mListener->OnStopRequest(this, mListenerContext, status); } + MOZ_EVENT_TRACER_DONE(this, "net::http::channel"); + CloseCacheEntry(!contentComplete); if (mOfflineCacheEntry) @@ -5149,6 +5171,8 @@ nsHttpChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt, // already streamed some data from another source (see, for example, // OnDoneReadingPartialCacheEntry). // + if (!mLogicalOffset) + MOZ_EVENT_TRACER_EXEC(this, "net::http::channel"); nsresult rv = mListener->OnDataAvailable(this, mListenerContext, @@ -5446,6 +5470,10 @@ nsHttpChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, { MOZ_ASSERT(NS_IsMainThread()); + mozilla::eventtracer::AutoEventTracer profiler(this, + eventtracer::eNone, eventtracer::eDone, + "net::http::OpenCacheEntry"); + nsresult rv; LOG(("nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p " @@ -5791,6 +5819,7 @@ nsHttpChannel::OnRedirectVerifyCallback(nsresult result) // We are not waiting for the callback. At this moment we must release // reference to the redirect target channel, otherwise we may leak. mRedirectChannel = nullptr; + MOZ_EVENT_TRACER_DONE(this, "net::http::channel"); } // We always resume the pumps here. If all functions on stack have been diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 86641333eab0..0b38384e6383 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -20,6 +20,7 @@ #include "nsISSLSocketControl.h" #include "prnetdb.h" #include "mozilla/Telemetry.h" +#include "mozilla/VisualEventTracer.h" #include using namespace mozilla; diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index ae3c0ac9a8e2..cea4aef408a0 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -23,6 +23,7 @@ #include "nsISocketTransport.h" #include "nsMultiplexInputStream.h" #include "nsStringStream.h" +#include "mozilla/VisualEventTracer.h" #include "nsComponentManagerUtils.h" // do_CreateInstance #include "nsServiceManagerUtils.h" // do_GetService @@ -180,6 +181,12 @@ nsHttpTransaction::Init(uint32_t caps, nsITransportEventSink *eventsink, nsIAsyncInputStream **responseBody) { + MOZ_EVENT_TRACER_COMPOUND_NAME(static_cast(this), + requestHead->PeekHeader(nsHttp::Host), + requestHead->RequestURI().BeginReading()); + + MOZ_EVENT_TRACER_WAIT(static_cast(this), + "net::http::transaction"); nsresult rv; LOG(("nsHttpTransaction::Init [this=%x caps=%x]\n", this, caps)); @@ -393,6 +400,11 @@ nsHttpTransaction::SetConnection(nsAHttpConnection *conn) { NS_IF_RELEASE(mConnection); NS_IF_ADDREF(mConnection = conn); + + if (conn) { + MOZ_EVENT_TRACER_EXEC(static_cast(this), + "net::http::transaction"); + } } void @@ -536,6 +548,12 @@ nsHttpTransaction::ReadRequestSegment(nsIInputStream *stream, // First data we're sending -> this is requestStart trans->mTimings.requestStart = TimeStamp::Now(); } + + if (!trans->mSentData) { + MOZ_EVENT_TRACER_MARK(static_cast(trans), + "net::http::first-write"); + } + trans->mSentData = true; return NS_OK; } @@ -606,6 +624,11 @@ nsHttpTransaction::WritePipeSegment(nsIOutputStream *stream, rv = trans->mWriter->OnWriteSegment(buf, count, countWritten); if (NS_FAILED(rv)) return rv; // caller didn't want to write anything + if (!trans->mReceivedData) { + MOZ_EVENT_TRACER_MARK(static_cast(trans), + "net::http::first-read"); + } + NS_ASSERTION(*countWritten > 0, "bad writer"); trans->mReceivedData = true; @@ -805,6 +828,9 @@ nsHttpTransaction::Close(nsresult reason) // closing this pipe triggers the channel's OnStopRequest method. mPipeOut->CloseWithStatus(reason); + + MOZ_EVENT_TRACER_DONE(static_cast(this), + "net::http::transaction"); } nsresult