summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-12-12 12:41:26 +0000
committerMoonchild <moonchild@palemoon.org>2020-12-12 12:41:26 +0000
commit2fa993b5639e04c7e1d7403ecf9175a223ce50b4 (patch)
tree99e2f5cdd5415e0d7eb3e24f80f5901be23611c6
parent4281fcc163f2a9ddf8409d6491d54a4620c037bf (diff)
downloadUXP-2fa993b5639e04c7e1d7403ecf9175a223ce50b4.tar
UXP-2fa993b5639e04c7e1d7403ecf9175a223ce50b4.tar.gz
UXP-2fa993b5639e04c7e1d7403ecf9175a223ce50b4.tar.lz
UXP-2fa993b5639e04c7e1d7403ecf9175a223ce50b4.tar.xz
UXP-2fa993b5639e04c7e1d7403ecf9175a223ce50b4.zip
Issue #1695 - Add clamping to websocket polling timeouts.
-rw-r--r--modules/libpref/init/all.js5
-rw-r--r--netwerk/base/nsSocketTransportService2.cpp23
-rw-r--r--netwerk/base/nsSocketTransportService2.h5
3 files changed, 30 insertions, 3 deletions
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index b6af98863..8fcebed74 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1660,6 +1660,11 @@ pref("network.websocket.timeout.open", 20);
// close message
pref("network.websocket.timeout.close", 20);
+// Setting this to true will clamp the websocket timeout value to a minimum
+// regardless if there are pending events on the thread.
+// This is a workaround for runaway polling, see issue #1695
+pref("network.websocket.timeout.clamped", false);
+
// the number of seconds of idle read activity to sustain before sending a
// ping probe. 0 to disable.
pref("network.websocket.timeout.ping.request", 0);
diff --git a/netwerk/base/nsSocketTransportService2.cpp b/netwerk/base/nsSocketTransportService2.cpp
index 6631db655..956332953 100644
--- a/netwerk/base/nsSocketTransportService2.cpp
+++ b/netwerk/base/nsSocketTransportService2.cpp
@@ -42,6 +42,7 @@ Atomic<PRThread*, Relaxed> gSocketThread;
#define KEEPALIVE_PROBE_COUNT_PREF "network.tcp.keepalive.probe_count"
#define SOCKET_LIMIT_TARGET 1000U
#define SOCKET_LIMIT_MIN 50U
+#define SOCKET_CLAMP_PREF "network.websocket.timeout.clamped"
#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_FOR_PR_CLOSE_DURING_SHUTDOWN "network.sts.max_time_for_pr_close_during_shutdown"
@@ -120,6 +121,7 @@ nsSocketTransportService::nsSocketTransportService()
, mKeepaliveEnabledPref(false)
, mServingPendingQueue(false)
, mMaxTimePerPollIter(100)
+ , mClampSocketTimeout(false)
, mMaxTimeForPrClosePref(PR_SecondsToInterval(5))
, mProbedMaxCount(false)
#if defined(XP_WIN)
@@ -485,7 +487,11 @@ nsSocketTransportService::Poll(PRIntervalTime ts)
mPollList[0].out_flags = 0;
pollList = mPollList;
pollCount = mActiveCount + 1;
- pollTimeout = pendingEvents ? PR_INTERVAL_NO_WAIT : PollTimeout(ts);
+ pollTimeout = IsSocketTimeoutClamped() ?
+ PR_MillisecondsToInterval(100) :
+ pendingEvents ?
+ PR_INTERVAL_NO_WAIT :
+ PollTimeout(ts);
}
else {
// no pollable event, so busy wait...
@@ -494,8 +500,11 @@ nsSocketTransportService::Poll(PRIntervalTime ts)
pollList = &mPollList[1];
else
pollList = nullptr;
- pollTimeout =
- pendingEvents ? PR_INTERVAL_NO_WAIT : PR_MillisecondsToInterval(25);
+ pollTimeout = IsSocketTimeoutClamped() ?
+ PR_MillisecondsToInterval(25) :
+ pendingEvents ?
+ PR_INTERVAL_NO_WAIT :
+ PR_MillisecondsToInterval(25);
}
SOCKET_LOG((" timeout = %i milliseconds\n",
@@ -554,6 +563,7 @@ nsSocketTransportService::Init()
tmpPrefService->AddObserver(KEEPALIVE_RETRY_INTERVAL_PREF, this, false);
tmpPrefService->AddObserver(KEEPALIVE_PROBE_COUNT_PREF, this, false);
tmpPrefService->AddObserver(MAX_TIME_BETWEEN_TWO_POLLS, this, false);
+ tmpPrefService->AddObserver(SOCKET_CLAMP_PREF, this, false);
tmpPrefService->AddObserver(MAX_TIME_FOR_PR_CLOSE_DURING_SHUTDOWN, this, false);
}
UpdatePrefs();
@@ -1150,6 +1160,13 @@ nsSocketTransportService::UpdatePrefs()
if (NS_SUCCEEDED(rv) && maxTimePref >= 0) {
mMaxTimePerPollIter = maxTimePref;
}
+
+ bool socketTimeoutClamped = false;
+ rv = tmpPrefService->GetBoolPref(SOCKET_CLAMP_PREF,
+ &socketTimeoutClamped);
+ if (NS_SUCCEEDED(rv)) {
+ mClampSocketTimeout = socketTimeoutClamped;
+ }
int32_t maxTimeForPrClosePref;
rv = tmpPrefService->GetIntPref(MAX_TIME_FOR_PR_CLOSE_DURING_SHUTDOWN,
diff --git a/netwerk/base/nsSocketTransportService2.h b/netwerk/base/nsSocketTransportService2.h
index 31efec1d9..9360dd905 100644
--- a/netwerk/base/nsSocketTransportService2.h
+++ b/netwerk/base/nsSocketTransportService2.h
@@ -116,6 +116,9 @@ public:
// Returns true if keepalives are enabled in prefs.
bool IsKeepaliveEnabled() { return mKeepaliveEnabledPref; }
+
+ // Returns true if socket timeout clamping is enabled in prefs.
+ bool IsSocketTimeoutClamped() { return mClampSocketTimeout; }
PRIntervalTime MaxTimeForPrClosePref() {return mMaxTimeForPrClosePref; }
protected:
@@ -253,6 +256,8 @@ private:
int32_t mKeepaliveProbeCount;
// True if TCP keepalive is enabled globally.
bool mKeepaliveEnabledPref;
+ // True if socket polling should be clamped.
+ bool mClampSocketTimeout;
Atomic<bool> mServingPendingQueue;
Atomic<int32_t, Relaxed> mMaxTimePerPollIter;