зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1240481 - Limit PR_Close calls during shutdown. r=mcmanus
This commit is contained in:
Родитель
854aecd889
Коммит
06c9cbac52
|
@ -1481,6 +1481,10 @@ pref("network.ftp.control.qos", 0);
|
||||||
|
|
||||||
// The max time to spend on xpcom events between two polls in ms.
|
// The max time to spend on xpcom events between two polls in ms.
|
||||||
pref("network.sts.max_time_for_events_between_two_polls", 100);
|
pref("network.sts.max_time_for_events_between_two_polls", 100);
|
||||||
|
|
||||||
|
// 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);
|
||||||
// </http>
|
// </http>
|
||||||
|
|
||||||
// 2147483647 == PR_INT32_MAX == ~2 GB
|
// 2147483647 == PR_INT32_MAX == ~2 GB
|
||||||
|
|
|
@ -190,6 +190,7 @@ nsIOService::nsIOService()
|
||||||
, mLastOfflineStateChange(PR_IntervalNow())
|
, mLastOfflineStateChange(PR_IntervalNow())
|
||||||
, mLastConnectivityChange(PR_IntervalNow())
|
, mLastConnectivityChange(PR_IntervalNow())
|
||||||
, mLastNetworkLinkChange(PR_IntervalNow())
|
, mLastNetworkLinkChange(PR_IntervalNow())
|
||||||
|
, mNetTearingDownStarted(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1419,6 +1420,7 @@ nsIOService::Observe(nsISupports *subject,
|
||||||
} else if (!strcmp(topic, kProfileChangeNetTeardownTopic)) {
|
} else if (!strcmp(topic, kProfileChangeNetTeardownTopic)) {
|
||||||
if (!mOffline) {
|
if (!mOffline) {
|
||||||
mOfflineForProfileChange = true;
|
mOfflineForProfileChange = true;
|
||||||
|
mNetTearingDownStarted = PR_IntervalNow();
|
||||||
if (gHttpHandler) {
|
if (gHttpHandler) {
|
||||||
gHttpHandler->ShutdownConnectionManager();
|
gHttpHandler->ShutdownConnectionManager();
|
||||||
}
|
}
|
||||||
|
@ -1447,7 +1449,9 @@ nsIOService::Observe(nsISupports *subject,
|
||||||
// changes of the offline status from now. We must not allow going
|
// changes of the offline status from now. We must not allow going
|
||||||
// online after this point.
|
// online after this point.
|
||||||
mShutdown = true;
|
mShutdown = true;
|
||||||
|
if (!mOfflineForProfileChange) {
|
||||||
|
mNetTearingDownStarted = PR_IntervalNow();
|
||||||
|
}
|
||||||
if (gHttpHandler) {
|
if (gHttpHandler) {
|
||||||
gHttpHandler->ShutdownConnectionManager();
|
gHttpHandler->ShutdownConnectionManager();
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
PRIntervalTime LastConnectivityChange() { return mLastConnectivityChange; }
|
PRIntervalTime LastConnectivityChange() { return mLastConnectivityChange; }
|
||||||
PRIntervalTime LastNetworkLinkChange() { return mLastNetworkLinkChange; }
|
PRIntervalTime LastNetworkLinkChange() { return mLastNetworkLinkChange; }
|
||||||
bool IsNetTearingDown() { return mShutdown || mOfflineForProfileChange; }
|
bool IsNetTearingDown() { return mShutdown || mOfflineForProfileChange; }
|
||||||
|
PRIntervalTime NetTearingDownStarted() { return mNetTearingDownStarted; }
|
||||||
bool IsLinkUp();
|
bool IsLinkUp();
|
||||||
|
|
||||||
// Should only be called from NeckoChild. Use SetAppOffline instead.
|
// Should only be called from NeckoChild. Use SetAppOffline instead.
|
||||||
|
@ -180,9 +181,12 @@ private:
|
||||||
// PR_ConnectContinue and PR_Close blocking time. If we spend very long
|
// PR_ConnectContinue and PR_Close blocking time. If we spend very long
|
||||||
// time in any of these functions we want to know if and what network
|
// time in any of these functions we want to know if and what network
|
||||||
// change has happened shortly before.
|
// change has happened shortly before.
|
||||||
mozilla::Atomic<PRIntervalTime> mLastOfflineStateChange;
|
mozilla::Atomic<PRIntervalTime> mLastOfflineStateChange;
|
||||||
mozilla::Atomic<PRIntervalTime> mLastConnectivityChange;
|
mozilla::Atomic<PRIntervalTime> mLastConnectivityChange;
|
||||||
mozilla::Atomic<PRIntervalTime> mLastNetworkLinkChange;
|
mozilla::Atomic<PRIntervalTime> mLastNetworkLinkChange;
|
||||||
|
|
||||||
|
// Time a network tearing down started.
|
||||||
|
mozilla::Atomic<PRIntervalTime> mNetTearingDownStarted;
|
||||||
public:
|
public:
|
||||||
// Used for all default buffer sizes that necko allocates.
|
// Used for all default buffer sizes that necko allocates.
|
||||||
static uint32_t gDefaultSegmentSize;
|
static uint32_t gDefaultSegmentSize;
|
||||||
|
|
|
@ -1748,7 +1748,12 @@ nsSocketTransport::ReleaseFD_Locked(PRFileDesc *fd)
|
||||||
SOCKET_LOG(("JIMB: ReleaseFD_Locked: mFDref = %d\n", mFDref));
|
SOCKET_LOG(("JIMB: ReleaseFD_Locked: mFDref = %d\n", mFDref));
|
||||||
|
|
||||||
if (--mFDref == 0) {
|
if (--mFDref == 0) {
|
||||||
if (PR_GetCurrentThread() == gSocketThread) {
|
if (gIOService->IsNetTearingDown() &&
|
||||||
|
((PR_IntervalNow() - gIOService->NetTearingDownStarted()) >
|
||||||
|
gSocketTransportService->MaxTimeForPrClosePref())) {
|
||||||
|
// If shutdown last to long, let the socket leak and do not close it.
|
||||||
|
SOCKET_LOG(("Intentional leak"));
|
||||||
|
} else if (PR_GetCurrentThread() == gSocketThread) {
|
||||||
SOCKET_LOG(("nsSocketTransport: calling PR_Close [this=%p]\n", this));
|
SOCKET_LOG(("nsSocketTransport: calling PR_Close [this=%p]\n", this));
|
||||||
PR_Close(mFD);
|
PR_Close(mFD);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -47,6 +47,7 @@ Atomic<PRThread*, Relaxed> gSocketThread;
|
||||||
#define BLIP_INTERVAL_PREF "network.activity.blipIntervalMilliseconds"
|
#define BLIP_INTERVAL_PREF "network.activity.blipIntervalMilliseconds"
|
||||||
#define MAX_TIME_BETWEEN_TWO_POLLS "network.sts.max_time_for_events_between_two_polls"
|
#define MAX_TIME_BETWEEN_TWO_POLLS "network.sts.max_time_for_events_between_two_polls"
|
||||||
#define TELEMETRY_PREF "toolkit.telemetry.enabled"
|
#define TELEMETRY_PREF "toolkit.telemetry.enabled"
|
||||||
|
#define MAX_TIME_FOR_PR_CLOSE_DURING_SHUTDOWN "network.sts.max_time_for_pr_close_during_shutdown"
|
||||||
|
|
||||||
uint32_t nsSocketTransportService::gMaxCount;
|
uint32_t nsSocketTransportService::gMaxCount;
|
||||||
PRCallOnceType nsSocketTransportService::gMaxCountInitOnce;
|
PRCallOnceType nsSocketTransportService::gMaxCountInitOnce;
|
||||||
|
@ -111,6 +112,7 @@ nsSocketTransportService::nsSocketTransportService()
|
||||||
, mServingPendingQueue(false)
|
, mServingPendingQueue(false)
|
||||||
, mMaxTimePerPollIter(100)
|
, mMaxTimePerPollIter(100)
|
||||||
, mTelemetryEnabledPref(false)
|
, mTelemetryEnabledPref(false)
|
||||||
|
, mMaxTimeForPrClosePref(PR_SecondsToInterval(5))
|
||||||
, mProbedMaxCount(false)
|
, mProbedMaxCount(false)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
|
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
|
||||||
|
@ -550,6 +552,7 @@ nsSocketTransportService::Init()
|
||||||
tmpPrefService->AddObserver(KEEPALIVE_PROBE_COUNT_PREF, this, false);
|
tmpPrefService->AddObserver(KEEPALIVE_PROBE_COUNT_PREF, this, false);
|
||||||
tmpPrefService->AddObserver(MAX_TIME_BETWEEN_TWO_POLLS, this, false);
|
tmpPrefService->AddObserver(MAX_TIME_BETWEEN_TWO_POLLS, this, false);
|
||||||
tmpPrefService->AddObserver(TELEMETRY_PREF, this, false);
|
tmpPrefService->AddObserver(TELEMETRY_PREF, this, false);
|
||||||
|
tmpPrefService->AddObserver(MAX_TIME_FOR_PR_CLOSE_DURING_SHUTDOWN, this, false);
|
||||||
}
|
}
|
||||||
UpdatePrefs();
|
UpdatePrefs();
|
||||||
|
|
||||||
|
@ -1218,6 +1221,13 @@ nsSocketTransportService::UpdatePrefs()
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
mTelemetryEnabledPref = telemetryPref;
|
mTelemetryEnabledPref = telemetryPref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t maxTimeForPrClosePref;
|
||||||
|
rv = tmpPrefService->GetIntPref(MAX_TIME_FOR_PR_CLOSE_DURING_SHUTDOWN,
|
||||||
|
&maxTimeForPrClosePref);
|
||||||
|
if (NS_SUCCEEDED(rv) && maxTimeForPrClosePref >=0) {
|
||||||
|
mMaxTimeForPrClosePref = PR_MillisecondsToInterval(maxTimeForPrClosePref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -112,6 +112,7 @@ public:
|
||||||
bool IsKeepaliveEnabled() { return mKeepaliveEnabledPref; }
|
bool IsKeepaliveEnabled() { return mKeepaliveEnabledPref; }
|
||||||
|
|
||||||
bool IsTelemetryEnabled() { return mTelemetryEnabledPref; }
|
bool IsTelemetryEnabled() { return mTelemetryEnabledPref; }
|
||||||
|
PRIntervalTime MaxTimeForPrClosePref() {return mMaxTimeForPrClosePref; }
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual ~nsSocketTransportService();
|
virtual ~nsSocketTransportService();
|
||||||
|
@ -237,6 +238,7 @@ private:
|
||||||
mozilla::Atomic<bool> mServingPendingQueue;
|
mozilla::Atomic<bool> mServingPendingQueue;
|
||||||
mozilla::Atomic<int32_t, mozilla::Relaxed> mMaxTimePerPollIter;
|
mozilla::Atomic<int32_t, mozilla::Relaxed> mMaxTimePerPollIter;
|
||||||
mozilla::Atomic<bool, mozilla::Relaxed> mTelemetryEnabledPref;
|
mozilla::Atomic<bool, mozilla::Relaxed> mTelemetryEnabledPref;
|
||||||
|
mozilla::Atomic<PRIntervalTime, mozilla::Relaxed> mMaxTimeForPrClosePref;
|
||||||
|
|
||||||
void OnKeepaliveEnabledPrefChange();
|
void OnKeepaliveEnabledPrefChange();
|
||||||
void NotifyKeepaliveEnabledPrefChange(SocketContext *sock);
|
void NotifyKeepaliveEnabledPrefChange(SocketContext *sock);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче