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

This commit is contained in:
Dragana Damjanovic 2015-02-18 06:35:00 -05:00
Родитель 7258683034
Коммит c39aefe5a8
3 изменённых файлов: 69 добавлений и 5 удалений

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

@ -1359,6 +1359,12 @@ pref("network.http.enforce-framing.http1", false);
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

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

@ -40,6 +40,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 +69,9 @@ nsSocketTransportService::nsSocketTransportService()
, mKeepaliveRetryIntervalS(1)
, mKeepaliveProbeCount(kDefaultTCPKeepCount)
, mKeepaliveEnabledPref(false)
, mServeMultipleEventsPerPollIter(true)
, mServingPendingQueue(false)
, mMaxTimePerPollIter(100)
, mProbedMaxCount(false)
{
#if defined(PR_LOGGING)
@ -481,6 +486,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 +693,12 @@ nsSocketTransportService::AfterProcessNextEvent(nsIThreadInternal* thread,
return NS_OK;
}
void
nsSocketTransportService::MarkTheLastElementOfPendingQueue()
{
mServingPendingQueue = false;
}
#ifdef MOZ_NUWA_PROCESS
#include "ipc/Nuwa.h"
#endif
@ -730,15 +743,39 @@ nsSocketTransportService::Run()
// If there are pending events for this thread then
// DoPollIteration() should service the network without blocking.
DoPollIteration(!pendingEvents);
// If nothing was pending before the poll, it might be now
if (!pendingEvents)
if (!pendingEvents) {
thread->HasPendingEvents(&pendingEvents);
}
if (pendingEvents) {
NS_ProcessNextEvent(thread);
pendingEvents = false;
thread->HasPendingEvents(&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 +1019,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;

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

@ -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;