Bug 1260218 - SocketTransportService socket expansion r=dragana

This commit is contained in:
Patrick McManus 2016-03-23 20:44:28 -04:00
Родитель ec0cba0fc1
Коммит ea8cc58c8b
4 изменённых файлов: 89 добавлений и 35 удалений

Просмотреть файл

@ -1323,10 +1323,13 @@ pref("network.http.keep-alive.timeout", 115);
pref("network.http.response.timeout", 300);
// Limit the absolute number of http connections.
// Note: the socket transport service will clamp the number below 256 if the OS
// cannot allocate that many FDs, and it also always tries to reserve up to 250
// file descriptors for things other than sockets.
// Note: the socket transport service will clamp the number below this if the OS
// cannot allocate that many FDs
#ifdef ANDROID
pref("network.http.max-connections", 256);
#else
pref("network.http.max-connections", 900);
#endif
// If NOT connecting via a proxy, then
// a new connection will only be attempted if the number of active persistent

Просмотреть файл

@ -41,8 +41,8 @@ Atomic<PRThread*, Relaxed> gSocketThread;
#define KEEPALIVE_IDLE_TIME_PREF "network.tcp.keepalive.idle_time"
#define KEEPALIVE_RETRY_INTERVAL_PREF "network.tcp.keepalive.retry_interval"
#define KEEPALIVE_PROBE_COUNT_PREF "network.tcp.keepalive.probe_count"
#define SOCKET_LIMIT_TARGET 550U
#define SOCKET_LIMIT_MIN 50U
#define SOCKET_LIMIT_TARGET 1000U
#define SOCKET_LIMIT_MIN 50U
#define BLIP_INTERVAL_PREF "network.activity.blipIntervalMilliseconds"
#define MAX_TIME_BETWEEN_TWO_POLLS "network.sts.max_time_for_events_between_two_polls"
#define TELEMETRY_PREF "toolkit.telemetry.enabled"
@ -226,6 +226,35 @@ nsSocketTransportService::AttachSocket(PRFileDesc *fd, nsASocketHandler *handler
return rv;
}
// the number of sockets that can be attached at any given time is
// limited. this is done because some operating systems (e.g., Win9x)
// limit the number of sockets that can be created by an application.
// AttachSocket will fail if the limit is exceeded. consumers should
// call CanAttachSocket and check the result before creating a socket.
bool
nsSocketTransportService::CanAttachSocket()
{
static bool reported900FDLimit = false;
static bool reported256FDLimit = false;
uint32_t total = mActiveCount + mIdleCount;
bool rv = total < gMaxCount;
if (mTelemetryEnabledPref) {
if (((total >= 900) || !rv) && !reported900FDLimit) {
reported900FDLimit = true;
Telemetry::Accumulate(Telemetry::NETWORK_SESSION_AT_900FD, true);
}
if ((total >= 256) && !reported256FDLimit) {
reported256FDLimit = true;
Telemetry::Accumulate(Telemetry::NETWORK_SESSION_AT_256FD, true);
}
}
return rv;
}
nsresult
nsSocketTransportService::DetachSocket(SocketContext *listHead, SocketContext *sock)
{
@ -378,11 +407,13 @@ bool
nsSocketTransportService::GrowActiveList()
{
int32_t toAdd = gMaxCount - mActiveListSize;
if (toAdd > 100)
if (toAdd > 100) {
toAdd = 100;
if (toAdd < 1)
} else if (toAdd < 1) {
MOZ_ASSERT(false, "CanAttachSocket() should prevent this");
return false;
}
mActiveListSize += toAdd;
mActiveList = (SocketContext *)
moz_xrealloc(mActiveList, sizeof(SocketContext) * mActiveListSize);
@ -395,10 +426,12 @@ bool
nsSocketTransportService::GrowIdleList()
{
int32_t toAdd = gMaxCount - mIdleListSize;
if (toAdd > 100)
if (toAdd > 100) {
toAdd = 100;
if (toAdd < 1)
} else if (toAdd < 1) {
MOZ_ASSERT(false, "CanAttachSocket() should prevent this");
return false;
}
mIdleListSize += toAdd;
mIdleList = (SocketContext *)
@ -794,7 +827,7 @@ nsSocketTransportService::Run()
}
#endif
SOCKET_LOG(("STS thread init\n"));
SOCKET_LOG(("STS thread init %d sockets\n", gMaxCount));
psm::InitializeSSLServerCertVerificationThreads();
@ -1407,6 +1440,7 @@ nsSocketTransportService::ProbeMaxCount()
if (pfd[index].fd)
PR_Close(pfd[index].fd);
Telemetry::Accumulate(Telemetry::NETWORK_PROBE_MAXCOUNT, gMaxCount);
SOCKET_LOG(("Socket Limit Test max was confirmed at %d\n", gMaxCount));
}
#endif // windows
@ -1420,35 +1454,37 @@ nsSocketTransportService::DiscoverMaxCount()
// On unix and os x network sockets and file
// descriptors are the same. OS X comes defaulted at 256,
// most linux at 1000. We can reliably use [sg]rlimit to
// query that and raise it. We will try to raise it 250 past
// our target number of SOCKET_LIMIT_TARGET so that some descriptors
// are still available for other things.
// query that and raise it if needed.
struct rlimit rlimitData;
if (getrlimit(RLIMIT_NOFILE, &rlimitData) == -1)
if (getrlimit(RLIMIT_NOFILE, &rlimitData) == -1) // rlimit broken - use min
return PR_SUCCESS;
if (rlimitData.rlim_cur >= SOCKET_LIMIT_TARGET + 250) {
if (rlimitData.rlim_cur >= SOCKET_LIMIT_TARGET) { // larger than target!
gMaxCount = SOCKET_LIMIT_TARGET;
return PR_SUCCESS;
}
int32_t maxallowed = rlimitData.rlim_max;
if (maxallowed == -1) { /* no limit */
maxallowed = SOCKET_LIMIT_TARGET + 250;
} else if ((uint32_t)maxallowed < SOCKET_LIMIT_MIN + 250) {
return PR_SUCCESS;
} else if ((uint32_t)maxallowed > SOCKET_LIMIT_TARGET + 250) {
maxallowed = SOCKET_LIMIT_TARGET + 250;
if ((uint32_t)maxallowed <= SOCKET_LIMIT_MIN) {
return PR_SUCCESS; // so small treat as if rlimit is broken
}
if ((maxallowed == -1) || // no hard cap - ok to set target
((uint32_t)maxallowed >= SOCKET_LIMIT_TARGET)) {
maxallowed = SOCKET_LIMIT_TARGET;
}
rlimitData.rlim_cur = maxallowed;
setrlimit(RLIMIT_NOFILE, &rlimitData);
if (getrlimit(RLIMIT_NOFILE, &rlimitData) != -1)
if (rlimitData.rlim_cur > SOCKET_LIMIT_MIN + 250)
gMaxCount = rlimitData.rlim_cur - 250;
if ((getrlimit(RLIMIT_NOFILE, &rlimitData) != -1) &&
(rlimitData.rlim_cur > SOCKET_LIMIT_MIN)) {
gMaxCount = rlimitData.rlim_cur;
}
#elif defined(XP_WIN) && !defined(WIN_CE)
// >= XP is confirmed to have at least 1000
PR_STATIC_ASSERT(SOCKET_LIMIT_TARGET <= 1000);
gMaxCount = SOCKET_LIMIT_TARGET;
#else
// other platforms are harder to test - so leave at safe legacy value

Просмотреть файл

@ -94,16 +94,7 @@ public:
static PRCallOnceType gMaxCountInitOnce;
static PRStatus DiscoverMaxCount();
//
// the number of sockets that can be attached at any given time is
// limited. this is done because some operating systems (e.g., Win9x)
// limit the number of sockets that can be created by an application.
// AttachSocket will fail if the limit is exceeded. consumers should
// call CanAttachSocket and check the result before creating a socket.
//
bool CanAttachSocket() {
return mActiveCount + mIdleCount < gMaxCount;
}
bool CanAttachSocket();
// Called by the networking dashboard on the socket thread only
// Fills the passed array with socket information

Просмотреть файл

@ -2766,6 +2766,30 @@
"kind": "boolean",
"description": "session used autodialer"
},
"NETWORK_SESSION_AT_256FD": {
"expires_in_version": "49",
"kind": "boolean",
"description": "session exceeded old 256 limit",
"bug_numbers": [1260218],
"alert_emails": ["necko@mozilla.com"]
},
"NETWORK_SESSION_AT_900FD": {
"expires_in_version": "never",
"kind": "boolean",
"description": "session reached 900 fd limit sockets",
"bug_numbers": [1260218],
"alert_emails": ["necko@mozilla.com"]
},
"NETWORK_PROBE_MAXCOUNT": {
"expires_in_version": "never",
"kind": "linear",
"low": 50,
"high": 1000,
"n_buckets": 10,
"description": "Result of nsSocketTransportService::ProbeMaxCount()",
"bug_numbers": [1260218],
"alert_emails": ["necko@mozilla.com"]
},
"FIND_PLUGINS": {
"alert_emails": ["perf-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",