Bug 1131557 - Serve multiple xpcom events in one poll iteration. r=mcmanus

This commit is contained in:
Dragana Damjanovic 2015-03-04 14:17:00 +01:00
parent fa79ef2aea
commit d25d9faf01
3 changed files with 70 additions and 5 deletions

View File

@ -1360,6 +1360,12 @@ pref("network.http.enforce-framing.soft", true);
pref("network.ftp.data.qos", 0);
pref("network.ftp.control.qos", 0);
// If this pref is false only one xpcom event will be served per poll
// iteration. This is the original behavior.
// If it is true multiple events will be served.
pref("network.sts.serve_multiple_events_per_poll_iteration", 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);
// </http>
// 2147483647 == PR_INT32_MAX == ~2 GB

View File

@ -19,6 +19,7 @@
#include "mozilla/PublicSSL.h"
#include "mozilla/ChaosMode.h"
#include "mozilla/PodOperations.h"
#include "mozilla/TimeStamp.h"
#include "nsThreadUtils.h"
#include "nsIFile.h"
@ -40,6 +41,8 @@ PRThread *gSocketThread = nullptr;
#define SOCKET_LIMIT_TARGET 550U
#define SOCKET_LIMIT_MIN 50U
#define BLIP_INTERVAL_PREF "network.activity.blipIntervalMilliseconds"
#define SERVE_MULTIPLE_EVENTS_PREF "network.sts.serve_multiple_events_per_poll_iteration"
#define MAX_TIME_BETWEEN_TWO_POLLS "network.sts.max_time_for_events_between_two_polls"
uint32_t nsSocketTransportService::gMaxCount;
PRCallOnceType nsSocketTransportService::gMaxCountInitOnce;
@ -67,6 +70,9 @@ nsSocketTransportService::nsSocketTransportService()
, mKeepaliveRetryIntervalS(1)
, mKeepaliveProbeCount(kDefaultTCPKeepCount)
, mKeepaliveEnabledPref(false)
, mServeMultipleEventsPerPollIter(true)
, mServingPendingQueue(false)
, mMaxTimePerPollIter(100)
, mProbedMaxCount(false)
{
#if defined(PR_LOGGING)
@ -481,6 +487,8 @@ nsSocketTransportService::Init()
tmpPrefService->AddObserver(KEEPALIVE_IDLE_TIME_PREF, this, false);
tmpPrefService->AddObserver(KEEPALIVE_RETRY_INTERVAL_PREF, this, false);
tmpPrefService->AddObserver(KEEPALIVE_PROBE_COUNT_PREF, this, false);
tmpPrefService->AddObserver(SERVE_MULTIPLE_EVENTS_PREF, this, false);
tmpPrefService->AddObserver(MAX_TIME_BETWEEN_TWO_POLLS, this, false);
}
UpdatePrefs();
@ -686,6 +694,12 @@ nsSocketTransportService::AfterProcessNextEvent(nsIThreadInternal* thread,
return NS_OK;
}
void
nsSocketTransportService::MarkTheLastElementOfPendingQueue()
{
mServingPendingQueue = false;
}
#ifdef MOZ_NUWA_PROCESS
#include "ipc/Nuwa.h"
#endif
@ -732,13 +746,37 @@ nsSocketTransportService::Run()
DoPollIteration(!pendingEvents);
// If nothing was pending before the poll, it might be now
if (!pendingEvents)
if (!pendingEvents) {
thread->HasPendingEvents(&pendingEvents);
}
if (pendingEvents) {
if (mServeMultipleEventsPerPollIter) {
if (!mServingPendingQueue) {
nsresult rv = Dispatch(NS_NewRunnableMethod(this,
&nsSocketTransportService::MarkTheLastElementOfPendingQueue),
nsIEventTarget::DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
NS_WARNING("Could not dispatch a new event on the "
"socket thread.");
} else {
mServingPendingQueue = true;
}
}
TimeStamp eventQueueStart = TimeStamp::NowLoRes();
do {
NS_ProcessNextEvent(thread);
pendingEvents = false;
thread->HasPendingEvents(&pendingEvents);
} while (pendingEvents && mServingPendingQueue &&
((TimeStamp::NowLoRes() -
eventQueueStart).ToMilliseconds() <
mMaxTimePerPollIter));
} else {
NS_ProcessNextEvent(thread);
pendingEvents = false;
thread->HasPendingEvents(&pendingEvents);
}
}
} while (pendingEvents);
@ -982,6 +1020,20 @@ nsSocketTransportService::UpdatePrefs()
mKeepaliveEnabledPref = keepaliveEnabled;
OnKeepaliveEnabledPrefChange();
}
bool serveMultiplePref = false;
rv = tmpPrefService->GetBoolPref(SERVE_MULTIPLE_EVENTS_PREF,
&serveMultiplePref);
if (NS_SUCCEEDED(rv)) {
mServeMultipleEventsPerPollIter = serveMultiplePref;
}
int32_t maxTimePref;
rv = tmpPrefService->GetIntPref(MAX_TIME_BETWEEN_TWO_POLLS,
&maxTimePref);
if (NS_SUCCEEDED(rv) && maxTimePref >= 0) {
mMaxTimePerPollIter = maxTimePref;
}
}
return NS_OK;

View File

@ -17,6 +17,7 @@
#include "nsIObserver.h"
#include "mozilla/Mutex.h"
#include "mozilla/net/DashboardTypes.h"
#include "mozilla/Atomics.h"
class nsASocketHandler;
struct PRPollDesc;
@ -217,6 +218,10 @@ private:
// True if TCP keepalive is enabled globally.
bool mKeepaliveEnabledPref;
bool mServeMultipleEventsPerPollIter;
mozilla::Atomic<bool> mServingPendingQueue;
int32_t mMaxTimePerPollIter;
void OnKeepaliveEnabledPrefChange();
void NotifyKeepaliveEnabledPrefChange(SocketContext *sock);
@ -233,6 +238,8 @@ private:
void DetachSocketWithGuard(bool aGuardLocals,
SocketContext *socketList,
int32_t index);
void MarkTheLastElementOfPendingQueue();
};
extern nsSocketTransportService *gSocketTransportService;