зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1442178
- Do a busy wait of socket poll() shortly after network change detection, r=dragana
This commit is contained in:
Родитель
dab22ca3b9
Коммит
8a9d38fe70
|
@ -1783,6 +1783,16 @@ pref("network.ftp.enabled", true);
|
|||
// The max time to spend on xpcom events between two polls in ms.
|
||||
pref("network.sts.max_time_for_events_between_two_polls", 100);
|
||||
|
||||
// The number of seconds we don't let poll() handing indefinitely after network
|
||||
// link change has been detected so we can detect breakout of the pollable event.
|
||||
// Expected in seconds, 0 to disable.
|
||||
pref("network.sts.poll_busy_wait_period", 50);
|
||||
|
||||
// The number of seconds we cap poll() timeout to during the network link change
|
||||
// detection period.
|
||||
// Expected in seconds, 0 to disable.
|
||||
pref("network.sts.poll_busy_wait_period_timeout", 7);
|
||||
|
||||
// During shutdown we limit PR_Close calls. If time exceeds this pref (in ms)
|
||||
// let sockets just leak.
|
||||
pref("network.sts.max_time_for_pr_close_during_shutdown", 5000);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "mozilla/net/DNS.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "mozilla/dom/ClientInfo.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
||||
|
@ -1554,12 +1555,30 @@ nsIOService::GetManageOfflineStatus(bool* aManage)
|
|||
nsresult
|
||||
nsIOService::OnNetworkLinkEvent(const char *data)
|
||||
{
|
||||
LOG(("nsIOService::OnNetworkLinkEvent data:%s\n", data));
|
||||
if (!mNetworkLinkService)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (IsNeckoChild()) {
|
||||
// There is nothing IO service could do on the child process
|
||||
// with this at the moment. Feel free to add functionality
|
||||
// here at will, though.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mShutdown)
|
||||
if (mShutdown) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCString dataAsString(data);
|
||||
for (auto* cp : mozilla::dom::ContentParent::AllProcesses(mozilla::dom::ContentParent::eLive)) {
|
||||
PNeckoParent* neckoParent = SingleManagedOrNull(cp->ManagedPNeckoParent());
|
||||
if (!neckoParent) {
|
||||
continue;
|
||||
}
|
||||
Unused << neckoParent->SendNetworkChangeNotification(dataAsString);
|
||||
}
|
||||
|
||||
LOG(("nsIOService::OnNetworkLinkEvent data:%s\n", data));
|
||||
if (!mNetworkLinkService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!mManageLinkStatus) {
|
||||
LOG(("nsIOService::OnNetworkLinkEvent mManageLinkStatus=false\n"));
|
||||
|
@ -1573,7 +1592,8 @@ nsIOService::OnNetworkLinkEvent(const char *data)
|
|||
// but the status of the captive portal may have changed.
|
||||
RecheckCaptivePortal();
|
||||
return NS_OK;
|
||||
} else if (!strcmp(data, NS_NETWORK_LINK_DATA_DOWN)) {
|
||||
}
|
||||
if (!strcmp(data, NS_NETWORK_LINK_DATA_DOWN)) {
|
||||
isUp = false;
|
||||
} else if (!strcmp(data, NS_NETWORK_LINK_DATA_UP)) {
|
||||
isUp = true;
|
||||
|
|
|
@ -51,6 +51,8 @@ static Atomic<PRThread*, Relaxed> gSocketThread;
|
|||
#define SOCKET_LIMIT_MIN 50U
|
||||
#define INTERVAL_PREF "network.activity.intervalMilliseconds"
|
||||
#define MAX_TIME_BETWEEN_TWO_POLLS "network.sts.max_time_for_events_between_two_polls"
|
||||
#define POLL_BUSY_WAIT_PERIOD "network.sts.poll_busy_wait_period"
|
||||
#define POLL_BUSY_WAIT_PERIOD_TIMEOUT "network.sts.poll_busy_wait_period_timeout"
|
||||
#define TELEMETRY_PREF "toolkit.telemetry.enabled"
|
||||
#define MAX_TIME_FOR_PR_CLOSE_DURING_SHUTDOWN "network.sts.max_time_for_pr_close_during_shutdown"
|
||||
#define POLLABLE_EVENT_TIMEOUT "network.sts.pollable_event_timeout"
|
||||
|
@ -141,6 +143,9 @@ nsSocketTransportService::nsSocketTransportService()
|
|||
, mMaxTimePerPollIter(100)
|
||||
, mTelemetryEnabledPref(false)
|
||||
, mMaxTimeForPrClosePref(PR_SecondsToInterval(5))
|
||||
, mLastNetworkLinkChangeTime(0)
|
||||
, mNetworkLinkChangeBusyWaitPeriod(PR_SecondsToInterval(50))
|
||||
, mNetworkLinkChangeBusyWaitTimeout(PR_SecondsToInterval(7))
|
||||
, mSleepPhase(false)
|
||||
, mProbedMaxCount(false)
|
||||
#if defined(XP_WIN)
|
||||
|
@ -541,6 +546,16 @@ nsSocketTransportService::Poll(TimeDuration *pollDuration,
|
|||
pendingEvents ? PR_INTERVAL_NO_WAIT : PR_MillisecondsToInterval(25);
|
||||
}
|
||||
|
||||
if ((ts - mLastNetworkLinkChangeTime) < mNetworkLinkChangeBusyWaitPeriod) {
|
||||
// Being here means we are few seconds after a network change has
|
||||
// been detected.
|
||||
PRIntervalTime to = mNetworkLinkChangeBusyWaitTimeout;
|
||||
if (to) {
|
||||
pollTimeout = std::min(to, pollTimeout);
|
||||
SOCKET_LOG((" timeout shorthened after network change event"));
|
||||
}
|
||||
}
|
||||
|
||||
TimeStamp pollStart;
|
||||
if (mTelemetryEnabledPref) {
|
||||
pollStart = TimeStamp::NowLoRes();
|
||||
|
@ -619,6 +634,7 @@ nsSocketTransportService::Init()
|
|||
obsSvc->AddObserver(this, NS_WIDGET_SLEEP_OBSERVER_TOPIC, true);
|
||||
obsSvc->AddObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC, true);
|
||||
obsSvc->AddObserver(this, "xpcom-shutdown-threads", false);
|
||||
obsSvc->AddObserver(this, NS_NETWORK_LINK_TOPIC, false);
|
||||
}
|
||||
|
||||
mInitialized = true;
|
||||
|
@ -687,6 +703,7 @@ nsSocketTransportService::ShutdownThread()
|
|||
obsSvc->RemoveObserver(this, NS_WIDGET_SLEEP_OBSERVER_TOPIC);
|
||||
obsSvc->RemoveObserver(this, NS_WIDGET_WAKE_OBSERVER_TOPIC);
|
||||
obsSvc->RemoveObserver(this, "xpcom-shutdown-threads");
|
||||
obsSvc->RemoveObserver(this, NS_NETWORK_LINK_TOPIC);
|
||||
}
|
||||
|
||||
if (mAfterWakeUpTimer) {
|
||||
|
@ -1336,6 +1353,18 @@ nsSocketTransportService::UpdatePrefs()
|
|||
mMaxTimePerPollIter = maxTimePref;
|
||||
}
|
||||
|
||||
int32_t pollBusyWaitPeriod;
|
||||
rv = tmpPrefService->GetIntPref(POLL_BUSY_WAIT_PERIOD, &pollBusyWaitPeriod);
|
||||
if (NS_SUCCEEDED(rv) && pollBusyWaitPeriod > 0) {
|
||||
mNetworkLinkChangeBusyWaitPeriod = PR_SecondsToInterval(pollBusyWaitPeriod);
|
||||
}
|
||||
|
||||
int32_t pollBusyWaitPeriodTimeout;
|
||||
rv = tmpPrefService->GetIntPref(POLL_BUSY_WAIT_PERIOD_TIMEOUT, &pollBusyWaitPeriodTimeout);
|
||||
if (NS_SUCCEEDED(rv) && pollBusyWaitPeriodTimeout > 0) {
|
||||
mNetworkLinkChangeBusyWaitTimeout = PR_SecondsToInterval(pollBusyWaitPeriodTimeout);
|
||||
}
|
||||
|
||||
bool telemetryPref = false;
|
||||
rv = tmpPrefService->GetBoolPref(TELEMETRY_PREF,
|
||||
&telemetryPref);
|
||||
|
@ -1409,6 +1438,8 @@ nsSocketTransportService::Observe(nsISupports *subject,
|
|||
const char *topic,
|
||||
const char16_t *data)
|
||||
{
|
||||
SOCKET_LOG(("nsSocketTransportService::Observe topic=%s", topic));
|
||||
|
||||
if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||||
UpdatePrefs();
|
||||
return NS_OK;
|
||||
|
@ -1458,6 +1489,8 @@ nsSocketTransportService::Observe(nsISupports *subject,
|
|||
}
|
||||
} else if (!strcmp(topic, "xpcom-shutdown-threads")) {
|
||||
ShutdownThread();
|
||||
} else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
|
||||
mLastNetworkLinkChangeTime = PR_IntervalNow();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -254,6 +254,15 @@ private:
|
|||
Atomic<int32_t, Relaxed> mMaxTimePerPollIter;
|
||||
Atomic<bool, Relaxed> mTelemetryEnabledPref;
|
||||
Atomic<PRIntervalTime, Relaxed> mMaxTimeForPrClosePref;
|
||||
// Timestamp of the last network link change event, tracked
|
||||
// also on child processes.
|
||||
Atomic<PRIntervalTime, Relaxed> mLastNetworkLinkChangeTime;
|
||||
// Preference for how long we do busy wait after network link
|
||||
// change has been detected.
|
||||
Atomic<PRIntervalTime, Relaxed> mNetworkLinkChangeBusyWaitPeriod;
|
||||
// Preference for the value of timeout for poll() we use during
|
||||
// the network link change event period.
|
||||
Atomic<PRIntervalTime, Relaxed> mNetworkLinkChangeBusyWaitTimeout;
|
||||
|
||||
// Between a computer going to sleep and waking up the PR_*** telemetry
|
||||
// will be corrupted - so do not record it.
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "nsIOService.h"
|
||||
#include "nsINetworkPredictor.h"
|
||||
#include "nsINetworkPredictorVerifier.h"
|
||||
#include "nsINetworkLinkService.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
|
@ -450,6 +451,17 @@ NeckoChild::RecvSpeculativeConnectRequest()
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
NeckoChild::RecvNetworkChangeNotification(nsCString const& type)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
|
||||
if (obsService) {
|
||||
obsService->NotifyObservers(nullptr, NS_NETWORK_LINK_TOPIC,
|
||||
NS_ConvertUTF8toUTF16(type).get());
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ protected:
|
|||
virtual mozilla::ipc::IPCResult RecvPredOnPredictDNS(const URIParams& aURI) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvSpeculativeConnectRequest() override;
|
||||
virtual mozilla::ipc::IPCResult RecvNetworkChangeNotification(nsCString const& type) override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -147,6 +147,10 @@ child:
|
|||
|
||||
async SpeculativeConnectRequest();
|
||||
|
||||
// Using high priority to deliver this notification possibly sooner than we
|
||||
// enter poll() on the child process with infinite timeout.
|
||||
prio(high) async NetworkChangeNotification(nsCString type);
|
||||
|
||||
async PTransportProvider();
|
||||
|
||||
both:
|
||||
|
|
Загрузка…
Ссылка в новой задаче