Files
palemoon27/netwerk/base/NetworkActivityMonitor.cpp
T
roytam1 65d6aee9e0 import change from rmottola/Arctic-Fox:
- Bug 1132141 - Update storage when ServiceWorker registration fails. (5bf56ab4f)
- Bug 1001691 - WorkerPrivate::LoadInfo -> WorkerLoadInfo (bc017200f)
- Bug 1001691 - Move WorkerType out of WorkerPrivate.h (02751f7b6)
- Bug 1131882 - Associate ServiceWorkers with underlying ServiceWorkerInfo. (4492ae042)
- Bug 1131874 - ServiceWorker persistence activation fixes. (cd4f32309)
- Bug 1142015 - Add source for messages dispatched to a Service Worker. (25b685a06)
- Bug 1053275 - Exempt ServiceWorkers from per domain thread limits. (f67251f0d)
- Bug 1139561 - Various small ServiceWorker test fixes. (dbd0beae4)
- Bug 1130688 - Implement additional scope checking in service worker registration. (cbd8fee66)
- Bug 1142841: Convert all nsRefPtr<nsIRunnable> to nsCOMPtr<nsIRunnable>. r=ehsan (9d4e51880)
- Bug 1134462 - Synthesize status and headers from Response returned by ServiceWorker. (8203ae32b)
- Bug 1134462 - allow null body. (1490bb9bd)
- Bug 1141332 - Disable content decoding and use decoded length on intercepted channels. (2eec7968b)
- Bug 1134330 - Mark fetch events as reloads appropriately. (a3025a42a)
- Bug 1136757 - Add direct Response overload for FetchEvent.respondWith(). (a33248935)
- Bug 1134462 - Cleanup Promise usage in fetch test SW. (fbe9f4cd5)
- Bug 1134462 followup: Add missing MOZ_OVERRIDE annotation to SynthesizeStatus impls in SynthesizeStatus.h. (fb34b64d4)
- Bug 1142124 - Never revalidate cache entries for synthesized responses. (0f4842e41)
- Bug 1143155 - Filtered response stores internal response and allows access to headers. (956c334b1)
- Bug 1133861 - Enable the Fetch API by default. (e05918105)
- Bug 1140791 - Run fetch tests on main thread and workers. (e672969d6)
- Bug 1144819 - Change JS_DefineProperty APIs to treat getter=nullptr and setter=nullptr as indicating class getter/setter ops only for data properties. (e030ab7d6)
2019-06-18 20:09:32 +08:00

302 lines
8.5 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "NetworkActivityMonitor.h"
#include "prmem.h"
#include "nsIObserverService.h"
#include "nsPISocketTransportService.h"
#include "nsSocketTransportService2.h"
#include "nsThreadUtils.h"
#include "mozilla/Services.h"
#include "prerror.h"
using namespace mozilla::net;
static PRStatus
nsNetMon_Connect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
{
PRStatus ret;
PRErrorCode code;
ret = fd->lower->methods->connect(fd->lower, addr, timeout);
if (ret == PR_SUCCESS || (code = PR_GetError()) == PR_WOULD_BLOCK_ERROR ||
code == PR_IN_PROGRESS_ERROR)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
return ret;
}
static int32_t
nsNetMon_Read(PRFileDesc *fd, void *buf, int32_t len)
{
int32_t ret;
ret = fd->lower->methods->read(fd->lower, buf, len);
if (ret >= 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
return ret;
}
static int32_t
nsNetMon_Write(PRFileDesc *fd, const void *buf, int32_t len)
{
int32_t ret;
ret = fd->lower->methods->write(fd->lower, buf, len);
if (ret > 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
return ret;
}
static int32_t
nsNetMon_Writev(PRFileDesc *fd,
const PRIOVec *iov,
int32_t size,
PRIntervalTime timeout)
{
int32_t ret;
ret = fd->lower->methods->writev(fd->lower, iov, size, timeout);
if (ret > 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
return ret;
}
static int32_t
nsNetMon_Recv(PRFileDesc *fd,
void *buf,
int32_t amount,
int flags,
PRIntervalTime timeout)
{
int32_t ret;
ret = fd->lower->methods->recv(fd->lower, buf, amount, flags, timeout);
if (ret >= 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
return ret;
}
static int32_t
nsNetMon_Send(PRFileDesc *fd,
const void *buf,
int32_t amount,
int flags,
PRIntervalTime timeout)
{
int32_t ret;
ret = fd->lower->methods->send(fd->lower, buf, amount, flags, timeout);
if (ret > 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
return ret;
}
static int32_t
nsNetMon_RecvFrom(PRFileDesc *fd,
void *buf,
int32_t amount,
int flags,
PRNetAddr *addr,
PRIntervalTime timeout)
{
int32_t ret;
ret = fd->lower->methods->recvfrom(fd->lower,
buf,
amount,
flags,
addr,
timeout);
if (ret >= 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
return ret;
}
static int32_t
nsNetMon_SendTo(PRFileDesc *fd,
const void *buf,
int32_t amount,
int flags,
const PRNetAddr *addr,
PRIntervalTime timeout)
{
int32_t ret;
ret = fd->lower->methods->sendto(fd->lower,
buf,
amount,
flags,
addr,
timeout);
if (ret > 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
return ret;
}
static int32_t
nsNetMon_AcceptRead(PRFileDesc *listenSock,
PRFileDesc **acceptedSock,
PRNetAddr **peerAddr,
void *buf,
int32_t amount,
PRIntervalTime timeout)
{
int32_t ret;
ret = listenSock->lower->methods->acceptread(listenSock->lower,
acceptedSock,
peerAddr,
buf,
amount,
timeout);
if (ret > 0)
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
return ret;
}
class NotifyNetworkActivity : public nsRunnable {
public:
explicit NotifyNetworkActivity(NetworkActivityMonitor::Direction aDirection)
: mDirection(aDirection)
{}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs)
return NS_ERROR_FAILURE;
obs->NotifyObservers(nullptr,
mDirection == NetworkActivityMonitor::kUpload
? NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC
: NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC,
nullptr);
return NS_OK;
}
private:
nsCOMPtr<nsIObserverService> mObs;
NetworkActivityMonitor::Direction mDirection;
};
NetworkActivityMonitor * NetworkActivityMonitor::gInstance = nullptr;
static PRDescIdentity sNetActivityMonitorLayerIdentity;
static PRIOMethods sNetActivityMonitorLayerMethods;
static PRIOMethods *sNetActivityMonitorLayerMethodsPtr = nullptr;
NetworkActivityMonitor::NetworkActivityMonitor()
: mBlipInterval(PR_INTERVAL_NO_TIMEOUT)
{
MOZ_COUNT_CTOR(NetworkActivityMonitor);
NS_ASSERTION(gInstance==nullptr,
"multiple NetworkActivityMonitor instances!");
}
NetworkActivityMonitor::~NetworkActivityMonitor()
{
MOZ_COUNT_DTOR(NetworkActivityMonitor);
gInstance = nullptr;
}
nsresult
NetworkActivityMonitor::Init(int32_t blipInterval)
{
nsresult rv;
if (gInstance)
return NS_ERROR_ALREADY_INITIALIZED;
NetworkActivityMonitor * mon = new NetworkActivityMonitor();
rv = mon->Init_Internal(blipInterval);
if (NS_FAILED(rv)) {
delete mon;
return rv;
}
gInstance = mon;
return NS_OK;
}
nsresult
NetworkActivityMonitor::Shutdown()
{
if (!gInstance)
return NS_ERROR_NOT_INITIALIZED;
delete gInstance;
return NS_OK;
}
nsresult
NetworkActivityMonitor::Init_Internal(int32_t blipInterval)
{
if (!sNetActivityMonitorLayerMethodsPtr) {
sNetActivityMonitorLayerIdentity =
PR_GetUniqueIdentity("network activity monitor layer");
sNetActivityMonitorLayerMethods = *PR_GetDefaultIOMethods();
sNetActivityMonitorLayerMethods.connect = nsNetMon_Connect;
sNetActivityMonitorLayerMethods.read = nsNetMon_Read;
sNetActivityMonitorLayerMethods.write = nsNetMon_Write;
sNetActivityMonitorLayerMethods.writev = nsNetMon_Writev;
sNetActivityMonitorLayerMethods.recv = nsNetMon_Recv;
sNetActivityMonitorLayerMethods.send = nsNetMon_Send;
sNetActivityMonitorLayerMethods.recvfrom = nsNetMon_RecvFrom;
sNetActivityMonitorLayerMethods.sendto = nsNetMon_SendTo;
sNetActivityMonitorLayerMethods.acceptread = nsNetMon_AcceptRead;
sNetActivityMonitorLayerMethodsPtr = &sNetActivityMonitorLayerMethods;
}
mBlipInterval = PR_MillisecondsToInterval(blipInterval);
// Set the last notification times to time that has just expired, so any
// activity even right now will trigger notification.
mLastNotificationTime[kUpload] = PR_IntervalNow() - mBlipInterval;
mLastNotificationTime[kDownload] = mLastNotificationTime[kUpload];
return NS_OK;
}
nsresult
NetworkActivityMonitor::AttachIOLayer(PRFileDesc *fd)
{
if (!gInstance)
return NS_OK;
PRFileDesc * layer;
PRStatus status;
layer = PR_CreateIOLayerStub(sNetActivityMonitorLayerIdentity,
sNetActivityMonitorLayerMethodsPtr);
if (!layer) {
return NS_ERROR_FAILURE;
}
status = PR_PushIOLayer(fd, PR_NSPR_IO_LAYER, layer);
if (status == PR_FAILURE) {
PR_DELETE(layer);
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
NetworkActivityMonitor::DataInOut(Direction direction)
{
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
if (gInstance) {
PRIntervalTime now = PR_IntervalNow();
if ((now - gInstance->mLastNotificationTime[direction]) >
gInstance->mBlipInterval) {
gInstance->mLastNotificationTime[direction] = now;
gInstance->PostNotification(direction);
}
}
return NS_OK;
}
void
NetworkActivityMonitor::PostNotification(Direction direction)
{
nsCOMPtr<nsIRunnable> ev = new NotifyNetworkActivity(direction);
NS_DispatchToMainThread(ev);
}