mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-14 14:02:47 +00:00
Merge mozilla-central to b2g-inbound
This commit is contained in:
commit
fd393640f5
@ -48,4 +48,16 @@ libs:: $(DIST)/bin/metro/chrome/pdfjs.manifest
|
||||
$(foreach exclude,$(exclude_files), -X $(srcdir)/pdfjs/$(exclude)) \
|
||||
$(DIST)/bin/metro/chrome
|
||||
$(call py_action,buildlist,$(DIST)/bin/metro/chrome.manifest 'manifest chrome/pdfjs.manifest')
|
||||
|
||||
ifdef NIGHTLY_BUILD
|
||||
$(DIST)/bin/metro/chrome/shumway.manifest: $(GLOBAL_DEPS)
|
||||
printf 'manifest shumway/chrome.manifest' > $@
|
||||
|
||||
libs:: $(DIST)/bin/metro/chrome/shumway.manifest
|
||||
$(PYTHON) $(topsrcdir)/config/nsinstall.py \
|
||||
$(srcdir)/shumway \
|
||||
$(foreach exclude,$(exclude_files), -X $(srcdir)/shumway/$(exclude)) \
|
||||
$(DIST)/bin/metro/chrome
|
||||
$(call py_action,buildlist,$(DIST)/bin/metro/chrome.manifest 'manifest chrome/shumway.manifest')
|
||||
endif
|
||||
endif
|
||||
|
@ -834,6 +834,10 @@ bin/libfreebl_32int64_3.so
|
||||
@BINPATH@/metro/chrome/chrome.manifest
|
||||
@BINPATH@/metro/chrome/@AB_CD@@JAREXT@
|
||||
@BINPATH@/metro/chrome/@AB_CD@.manifest
|
||||
#ifdef NIGHTLY_BUILD
|
||||
@BINPATH@/metro/chrome/shumway.manifest
|
||||
@BINPATH@/metro/chrome/shumway/*
|
||||
#endif
|
||||
@BINPATH@/metro/chrome/pdfjs.manifest
|
||||
@BINPATH@/metro/chrome/pdfjs/*
|
||||
@BINPATH@/metro/components
|
||||
|
@ -40,6 +40,12 @@ XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ShumwayUtils",
|
||||
"resource://shumway/ShumwayUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PdfJs",
|
||||
"resource://pdf.js/PdfJs.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
|
@ -115,6 +115,9 @@ var BrowserUI = {
|
||||
SettingsCharm.init();
|
||||
NavButtonSlider.init();
|
||||
SelectionHelperUI.init();
|
||||
#ifdef NIGHTLY_BUILD
|
||||
ShumwayUtils.init();
|
||||
#endif
|
||||
|
||||
// We can delay some initialization until after startup. We wait until
|
||||
// the first page is shown, then dispatch a UIReadyDelayed event.
|
||||
@ -151,6 +154,7 @@ var BrowserUI = {
|
||||
DialogUI.init();
|
||||
FormHelperUI.init();
|
||||
FindHelperUI.init();
|
||||
PdfJs.init();
|
||||
} catch(ex) {
|
||||
Util.dumpLn("Exception in delay load module:", ex.message);
|
||||
}
|
||||
|
@ -546,12 +546,16 @@ pref("browser.chrome.toolbar_tips", false);
|
||||
pref("pdfjs.disabled", true);
|
||||
// Used by pdf.js to know the first time firefox is run with it installed so it
|
||||
// can become the default pdf viewer.
|
||||
pref("pdfjs.firstRun", false);
|
||||
pref("pdfjs.firstRun", true);
|
||||
// The values of preferredAction and alwaysAskBeforeHandling before pdf.js
|
||||
// became the default.
|
||||
pref("pdfjs.previousHandler.preferredAction", 0);
|
||||
pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
pref("shumway.disabled", true);
|
||||
#endif
|
||||
|
||||
// The maximum amount of decoded image data we'll willingly keep around (we
|
||||
// might keep around more than this, but we'll try to get down to this value).
|
||||
// (This is intentionally on the high side; see bug 746055.)
|
||||
|
@ -2121,7 +2121,11 @@ nsSMILTimedElement::SampleFillValue()
|
||||
if (repeatDuration.IsDefinite()) {
|
||||
activeTime = std::min(repeatDuration.GetMillis(), activeTime);
|
||||
}
|
||||
} else if (mElementState == STATE_ACTIVE) {
|
||||
} else {
|
||||
MOZ_ASSERT(mElementState == STATE_ACTIVE,
|
||||
"Attempting to sample fill value when we're in an unexpected state "
|
||||
"(probably STATE_STARTUP)");
|
||||
|
||||
// If we are being asked to sample the fill value while active we *must*
|
||||
// have a repeat duration shorter than the active duration so use that.
|
||||
MOZ_ASSERT(GetRepeatDuration().IsDefinite(),
|
||||
|
@ -124,6 +124,12 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||
// Maximum amount of time that should elapse between incremental CC slices
|
||||
static const int64_t kICCIntersliceDelay = 32; // ms
|
||||
|
||||
// Time budget for an incremental CC slice
|
||||
static const int64_t kICCSliceBudget = 10; // ms
|
||||
|
||||
// Maximum total duration for an ICC
|
||||
static const uint32_t kMaxICCDuration = 2000; // ms
|
||||
|
||||
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
|
||||
// objects in the purple buffer.
|
||||
#define NS_CC_FORCED (2 * 60 * PR_USEC_PER_SEC) // 2 min
|
||||
@ -2019,6 +2025,22 @@ struct CycleCollectorStats
|
||||
|
||||
CycleCollectorStats gCCStats;
|
||||
|
||||
static int64_t
|
||||
ICCSliceTime()
|
||||
{
|
||||
// If CC is not incremental, use an unlimited budget.
|
||||
if (!sIncrementalCC) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If an ICC is in progress and is taking too long, finish it off.
|
||||
if (gCCStats.mBeginTime != 0 &&
|
||||
TimeBetween(gCCStats.mBeginTime, PR_Now()) >= kMaxICCDuration) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return kICCSliceBudget;
|
||||
}
|
||||
|
||||
static void
|
||||
PrepareForCycleCollection(int32_t aExtraForgetSkippableCalls = 0)
|
||||
@ -2076,15 +2098,18 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
|
||||
|
||||
//static
|
||||
void
|
||||
nsJSContext::ScheduledCycleCollectNow()
|
||||
nsJSContext::ScheduledCycleCollectNow(int64_t aSliceTime)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PROFILER_LABEL("CC", "ScheduledCycleCollectNow");
|
||||
|
||||
// Ideally, the slice time would be decreased by the amount of
|
||||
// time spent on PrepareForCycleCollection().
|
||||
PrepareForCycleCollection();
|
||||
nsCycleCollector_scheduledCollect();
|
||||
nsCycleCollector_scheduledCollect(aSliceTime);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2108,7 +2133,7 @@ ICCTimerFired(nsITimer* aTimer, void* aClosure)
|
||||
}
|
||||
}
|
||||
|
||||
nsJSContext::ScheduledCycleCollectNow();
|
||||
nsJSContext::ScheduledCycleCollectNow(ICCSliceTime());
|
||||
}
|
||||
|
||||
//static
|
||||
@ -2312,6 +2337,17 @@ ShouldTriggerCC(uint32_t aSuspected)
|
||||
sLastCCEndTime + NS_CC_FORCED < PR_Now());
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
TimeToNextCC()
|
||||
{
|
||||
if (sIncrementalCC) {
|
||||
return NS_CC_DELAY - kMaxICCDuration;
|
||||
}
|
||||
return NS_CC_DELAY;
|
||||
}
|
||||
|
||||
static_assert(NS_CC_DELAY > kMaxICCDuration, "ICC shouldn't reduce CC delay to 0");
|
||||
|
||||
static void
|
||||
CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
@ -2321,7 +2357,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
|
||||
static uint32_t ccDelay = NS_CC_DELAY;
|
||||
if (sCCLockedOut) {
|
||||
ccDelay = NS_CC_DELAY / 3;
|
||||
ccDelay = TimeToNextCC() / 3;
|
||||
|
||||
PRTime now = PR_Now();
|
||||
if (sCCLockedOutTime == 0) {
|
||||
@ -2344,7 +2380,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
// During early timer fires, we only run forgetSkippable. During the first
|
||||
// late timer fire, we decide if we are going to have a second and final
|
||||
// late timer fire, where we may begin to run the CC.
|
||||
const uint32_t numEarlyTimerFires = ccDelay / NS_CC_SKIPPABLE_DELAY - 2;
|
||||
uint32_t numEarlyTimerFires = ccDelay / NS_CC_SKIPPABLE_DELAY - 2;
|
||||
bool isLateTimerFire = sCCTimerFireCount > numEarlyTimerFires;
|
||||
uint32_t suspected = nsCycleCollector_suspectedCount();
|
||||
if (isLateTimerFire && ShouldTriggerCC(suspected)) {
|
||||
@ -2359,7 +2395,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
// We are in the final timer fire and still meet the conditions for
|
||||
// triggering a CC. Let CycleCollectNow finish the current IGC, if any,
|
||||
// because that will allow us to include the GC time in the CC pause.
|
||||
nsJSContext::ScheduledCycleCollectNow();
|
||||
nsJSContext::ScheduledCycleCollectNow(ICCSliceTime());
|
||||
}
|
||||
} else if ((sPreviousSuspectedCount + 100) <= suspected) {
|
||||
// Only do a forget skippable if there are more than a few new objects.
|
||||
@ -2367,7 +2403,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
}
|
||||
|
||||
if (isLateTimerFire) {
|
||||
ccDelay = NS_CC_DELAY;
|
||||
ccDelay = TimeToNextCC();
|
||||
|
||||
// We have either just run the CC or decided we don't want to run the CC
|
||||
// next time, so kill the timer.
|
||||
@ -2813,6 +2849,13 @@ SetMemoryGCDynamicMarkSlicePrefChangedCallback(const char* aPrefName, void* aClo
|
||||
JS_SetGCParameter(sRuntime, JSGC_DYNAMIC_MARK_SLICE, pref);
|
||||
}
|
||||
|
||||
static void
|
||||
SetIncrementalCCPrefChangedCallback(const char* aPrefName, void* aClosure)
|
||||
{
|
||||
bool pref = Preferences::GetBool(aPrefName);
|
||||
sIncrementalCC = pref;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
NS_DOMReadStructuredClone(JSContext* cx,
|
||||
JSStructuredCloneReader* reader,
|
||||
@ -3019,6 +3062,9 @@ nsJSContext::EnsureStatics()
|
||||
"javascript.options.mem.gc_decommit_threshold_mb",
|
||||
(void *)JSGC_DECOMMIT_THRESHOLD);
|
||||
|
||||
Preferences::RegisterCallbackAndCall(SetIncrementalCCPrefChangedCallback,
|
||||
"dom.cycle_collector.incremental");
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (!obs) {
|
||||
MOZ_CRASH();
|
||||
|
@ -101,11 +101,17 @@ public:
|
||||
IsShrinking aShrinking = NonShrinkingGC,
|
||||
int64_t aSliceMillis = 0);
|
||||
static void ShrinkGCBuffersNow();
|
||||
|
||||
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
|
||||
// called even if the previous collection was GC.
|
||||
static void CycleCollectNow(nsICycleCollectorListener *aListener = nullptr,
|
||||
int32_t aExtraForgetSkippableCalls = 0);
|
||||
static void ScheduledCycleCollectNow();
|
||||
|
||||
// If aSliceTime is negative, the CC will run to completion. If aSliceTime
|
||||
// is 0, only a minimum quantum of work will be done. Otherwise, aSliceTime
|
||||
// will be used as the time budget for the slice, in ms.
|
||||
static void ScheduledCycleCollectNow(int64_t aSliceTime);
|
||||
|
||||
static void BeginCycleCollectionCallback();
|
||||
static void EndCycleCollectionCallback(mozilla::CycleCollectorResults &aResults);
|
||||
|
||||
|
@ -2047,11 +2047,12 @@ nsRuleNode::ResolveVariableReferences(const nsStyleStructID aSID,
|
||||
&aContext->StyleVariables()->mVariables;
|
||||
nsCSSValueTokenStream* tokenStream = value->GetTokenStreamValue();
|
||||
|
||||
// XXX Should pass in sheet here (see bug 952338).
|
||||
parser.ParsePropertyWithVariableReferences(
|
||||
tokenStream->mPropertyID, tokenStream->mShorthandPropertyID,
|
||||
tokenStream->mTokenStream, variables, aRuleData,
|
||||
tokenStream->mSheetURI, tokenStream->mBaseURI,
|
||||
tokenStream->mSheetPrincipal, tokenStream->mSheet,
|
||||
tokenStream->mSheetPrincipal, nullptr,
|
||||
tokenStream->mLineNumber, tokenStream->mLineOffset);
|
||||
aRuleData->mCanStoreInRuleTree = false;
|
||||
anyTokenStreams = true;
|
||||
|
@ -713,6 +713,8 @@ pref("dom.sysmsg.enabled", false);
|
||||
// Enable pre-installed applications.
|
||||
pref("dom.webapps.useCurrentProfile", false);
|
||||
|
||||
pref("dom.cycle_collector.incremental", false);
|
||||
|
||||
// Parsing perf prefs. For now just mimic what the old code did.
|
||||
#ifndef XP_WIN
|
||||
pref("content.sink.pending_event_mode", 0);
|
||||
|
@ -1 +1 @@
|
||||
NSS_3_15_4_BETA9
|
||||
NSS_3_15_4_BETA10
|
||||
|
@ -146,7 +146,7 @@ endif
|
||||
# uses fibers).
|
||||
#
|
||||
# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no
|
||||
# cross-compilation.
|
||||
# cross-compilation, except on Windows, where it defaults to WIN95.
|
||||
#
|
||||
|
||||
#
|
||||
@ -185,7 +185,7 @@ ifeq ($(OS_ARCH), Windows_NT)
|
||||
endif
|
||||
endif
|
||||
#
|
||||
# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using
|
||||
# If uname -s returns "CYGWIN_NT-*", we assume that we are using
|
||||
# the uname.exe in the Cygwin tools.
|
||||
#
|
||||
ifeq (CYGWIN_NT,$(findstring CYGWIN_NT,$(OS_ARCH)))
|
||||
@ -205,7 +205,7 @@ ifeq (CYGWIN_NT,$(findstring CYGWIN_NT,$(OS_ARCH)))
|
||||
endif
|
||||
endif
|
||||
#
|
||||
# If uname -s returns "MINGW32_NT-5.1", we assume that we are using
|
||||
# If uname -s returns "MINGW32_NT-*", we assume that we are using
|
||||
# the uname.exe in the MSYS toolkit.
|
||||
#
|
||||
ifeq (MINGW32_NT,$(findstring MINGW32_NT,$(OS_ARCH)))
|
||||
@ -235,8 +235,12 @@ ifeq ($(OS_TARGET),Android)
|
||||
endif
|
||||
|
||||
ifndef OS_TARGET
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
OS_TARGET = WIN95
|
||||
else
|
||||
OS_TARGET = $(OS_ARCH)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET), WIN95)
|
||||
OS_RELEASE = 4.0
|
||||
|
@ -10,3 +10,4 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
@ -750,14 +750,23 @@ static PRBool
|
||||
ocsp_IsCacheItemFresh(OCSPCacheItem *cacheItem)
|
||||
{
|
||||
PRTime now;
|
||||
PRBool retval;
|
||||
PRBool fresh;
|
||||
|
||||
PR_EnterMonitor(OCSP_Global.monitor);
|
||||
now = PR_Now();
|
||||
retval = (cacheItem->nextFetchAttemptTime > now);
|
||||
OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", retval));
|
||||
PR_ExitMonitor(OCSP_Global.monitor);
|
||||
return retval;
|
||||
|
||||
fresh = cacheItem->nextFetchAttemptTime > now;
|
||||
|
||||
/* Work around broken OCSP responders that return unknown responses for
|
||||
* certificates, especially certificates that were just recently issued.
|
||||
*/
|
||||
if (fresh && cacheItem->certStatusArena &&
|
||||
cacheItem->certStatus.certStatusType == ocspCertStatus_unknown) {
|
||||
fresh = PR_FALSE;
|
||||
}
|
||||
|
||||
OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", fresh));
|
||||
|
||||
return fresh;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -784,6 +793,19 @@ ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
|
||||
PORT_Assert(OCSP_Global.maxCacheEntries >= 0);
|
||||
|
||||
cacheItem = ocsp_FindCacheEntry(cache, certID);
|
||||
|
||||
/* Don't replace an unknown or revoked entry with an error entry, even if
|
||||
* the existing entry is expired. Instead, we'll continue to use the
|
||||
* existing (possibly expired) cache entry until we receive a valid signed
|
||||
* response to replace it.
|
||||
*/
|
||||
if (!single && cacheItem && cacheItem->certStatusArena &&
|
||||
(cacheItem->certStatus.certStatusType == ocspCertStatus_revoked ||
|
||||
cacheItem->certStatus.certStatusType == ocspCertStatus_unknown)) {
|
||||
PR_ExitMonitor(OCSP_Global.monitor);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (!cacheItem) {
|
||||
CERTOCSPCertID *myCertID;
|
||||
if (certIDWasConsumed) {
|
||||
@ -4915,7 +4937,7 @@ ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single,
|
||||
return ocsp_CertHasGoodStatus(single->certStatus, time);
|
||||
}
|
||||
|
||||
/* Return value SECFailure means: not found or not fresh.
|
||||
/* SECFailure means the arguments were invalid.
|
||||
* On SECSuccess, the out parameters contain the OCSP status.
|
||||
* rvOcsp contains the overall result of the OCSP operation.
|
||||
* Depending on input parameter ignoreGlobalOcspFailureSetting,
|
||||
@ -4923,34 +4945,39 @@ ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single,
|
||||
* If the cached attempt to obtain OCSP information had resulted
|
||||
* in a failure, missingResponseError shows the error code of
|
||||
* that failure.
|
||||
* cacheFreshness is ocspMissing if no entry was found,
|
||||
* ocspFresh if a fresh entry was found, or
|
||||
* ocspStale if a stale entry was found.
|
||||
*/
|
||||
SECStatus
|
||||
ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
|
||||
PRTime time,
|
||||
PRBool ignoreGlobalOcspFailureSetting,
|
||||
SECStatus *rvOcsp,
|
||||
SECErrorCodes *missingResponseError)
|
||||
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
|
||||
PRTime time,
|
||||
PRBool ignoreGlobalOcspFailureSetting,
|
||||
SECStatus *rvOcsp,
|
||||
SECErrorCodes *missingResponseError,
|
||||
OCSPFreshness *cacheFreshness)
|
||||
{
|
||||
OCSPCacheItem *cacheItem = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
if (!certID || !missingResponseError || !rvOcsp) {
|
||||
if (!certID || !missingResponseError || !rvOcsp || !cacheFreshness) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
*rvOcsp = SECFailure;
|
||||
*missingResponseError = 0;
|
||||
*cacheFreshness = ocspMissing;
|
||||
|
||||
PR_EnterMonitor(OCSP_Global.monitor);
|
||||
cacheItem = ocsp_FindCacheEntry(&OCSP_Global.cache, certID);
|
||||
if (cacheItem && ocsp_IsCacheItemFresh(cacheItem)) {
|
||||
if (cacheItem) {
|
||||
*cacheFreshness = ocsp_IsCacheItemFresh(cacheItem) ? ocspFresh
|
||||
: ocspStale;
|
||||
/* having an arena means, we have a cached certStatus */
|
||||
if (cacheItem->certStatusArena) {
|
||||
*rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time);
|
||||
if (*rvOcsp != SECSuccess) {
|
||||
*missingResponseError = PORT_GetError();
|
||||
}
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
/*
|
||||
* No status cached, the previous attempt failed.
|
||||
@ -4958,17 +4985,17 @@ ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
|
||||
* However, if OCSP is optional, a recent OCSP failure is
|
||||
* an allowed good state.
|
||||
*/
|
||||
if (!ignoreGlobalOcspFailureSetting &&
|
||||
if (*cacheFreshness == ocspFresh &&
|
||||
!ignoreGlobalOcspFailureSetting &&
|
||||
OCSP_Global.ocspFailureMode ==
|
||||
ocspMode_FailureIsNotAVerificationFailure) {
|
||||
rv = SECSuccess;
|
||||
*rvOcsp = SECSuccess;
|
||||
}
|
||||
*missingResponseError = cacheItem->missingResponseError;
|
||||
}
|
||||
}
|
||||
PR_ExitMonitor(OCSP_Global.monitor);
|
||||
return rv;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -5039,9 +5066,10 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||
{
|
||||
CERTOCSPCertID *certID;
|
||||
PRBool certIDWasConsumed = PR_FALSE;
|
||||
SECStatus rv = SECFailure;
|
||||
SECStatus rv;
|
||||
SECStatus rvOcsp;
|
||||
SECErrorCodes dummy_error_code; /* we ignore this */
|
||||
SECErrorCodes cachedErrorCode;
|
||||
OCSPFreshness cachedResponseFreshness;
|
||||
|
||||
OCSP_TRACE_CERT(cert);
|
||||
OCSP_TRACE_TIME("## requested validity time:", time);
|
||||
@ -5049,21 +5077,41 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||
certID = CERT_CreateOCSPCertID(cert, time);
|
||||
if (!certID)
|
||||
return SECFailure;
|
||||
rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
|
||||
rv = ocsp_GetCachedOCSPResponseStatus(
|
||||
certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
|
||||
&rvOcsp, &dummy_error_code);
|
||||
if (rv == SECSuccess) {
|
||||
&rvOcsp, &cachedErrorCode, &cachedResponseFreshness);
|
||||
if (rv != SECSuccess) {
|
||||
CERT_DestroyOCSPCertID(certID);
|
||||
return SECFailure;
|
||||
}
|
||||
if (cachedResponseFreshness == ocspFresh) {
|
||||
CERT_DestroyOCSPCertID(certID);
|
||||
return rvOcsp;
|
||||
}
|
||||
rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg,
|
||||
|
||||
rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg,
|
||||
&certIDWasConsumed,
|
||||
&rvOcsp);
|
||||
if (rv != SECSuccess) {
|
||||
/* we were unable to obtain ocsp status. Check if we should
|
||||
* return cert status revoked. */
|
||||
rvOcsp = ocsp_FetchingFailureIsVerificationFailure() ?
|
||||
SECFailure : SECSuccess;
|
||||
PRErrorCode err = PORT_GetError();
|
||||
if (ocsp_FetchingFailureIsVerificationFailure()) {
|
||||
PORT_SetError(err);
|
||||
rvOcsp = SECFailure;
|
||||
} else if (cachedResponseFreshness == ocspStale &&
|
||||
(cachedErrorCode == SEC_ERROR_OCSP_UNKNOWN_CERT ||
|
||||
cachedErrorCode == SEC_ERROR_REVOKED_CERTIFICATE)) {
|
||||
/* If we couldn't get a response for a certificate that the OCSP
|
||||
* responder previously told us was bad, then assume it is still
|
||||
* bad until we hear otherwise, as it is very unlikely that the
|
||||
* certificate status has changed from "revoked" to "good" and it
|
||||
* is also unlikely that the certificate status has changed from
|
||||
* "unknown" to "good", except for some buggy OCSP responders.
|
||||
*/
|
||||
PORT_SetError(cachedErrorCode);
|
||||
rvOcsp = SECFailure;
|
||||
} else {
|
||||
rvOcsp = SECSuccess;
|
||||
}
|
||||
}
|
||||
if (!certIDWasConsumed) {
|
||||
CERT_DestroyOCSPCertID(certID);
|
||||
@ -5113,6 +5161,7 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
|
||||
SECErrorCodes dummy_error_code; /* we ignore this */
|
||||
CERTOCSPResponse *decodedResponse = NULL;
|
||||
CERTOCSPSingleResponse *singleResponse = NULL;
|
||||
OCSPFreshness freshness;
|
||||
|
||||
/* The OCSP cache can be in three states regarding this certificate:
|
||||
* + Good (cached, timely, 'good' response, or revoked in the future)
|
||||
@ -5160,10 +5209,14 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
|
||||
certID = CERT_CreateOCSPCertID(cert, time);
|
||||
if (!certID)
|
||||
return SECFailure;
|
||||
rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
|
||||
certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
|
||||
&rvOcsp, &dummy_error_code);
|
||||
if (rv == SECSuccess && rvOcsp == SECSuccess) {
|
||||
|
||||
/* We pass PR_TRUE for ignoreGlobalOcspFailureSetting so that a cached
|
||||
* error entry is not interpreted as being a 'Good' entry here.
|
||||
*/
|
||||
rv = ocsp_GetCachedOCSPResponseStatus(
|
||||
certID, time, PR_TRUE, /* ignoreGlobalOcspFailureSetting */
|
||||
&rvOcsp, &dummy_error_code, &freshness);
|
||||
if (rv == SECSuccess && rvOcsp == SECSuccess && freshness == ocspFresh) {
|
||||
/* The cached value is good. We don't want to waste time validating
|
||||
* this OCSP response. This is the first column in the table above. */
|
||||
CERT_DestroyOCSPCertID(certID);
|
||||
|
@ -41,12 +41,15 @@ cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
|
||||
PRBool addServiceLocator,
|
||||
CERTCertificate *signerCert);
|
||||
|
||||
typedef enum { ocspMissing, ocspFresh, ocspStale } OCSPFreshness;
|
||||
|
||||
SECStatus
|
||||
ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
|
||||
PRTime time,
|
||||
PRBool ignoreOcspFailureMode,
|
||||
SECStatus *rvOcsp,
|
||||
SECErrorCodes *missingResponseError);
|
||||
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
|
||||
PRTime time,
|
||||
PRBool ignoreOcspFailureMode,
|
||||
SECStatus *rvOcsp,
|
||||
SECErrorCodes *missingResponseError,
|
||||
OCSPFreshness *freshness);
|
||||
|
||||
/*
|
||||
* FUNCTION: cert_ProcessOCSPResponse
|
||||
|
@ -184,6 +184,7 @@ PKIX_PL_OcspCertID_GetFreshCacheStatus(
|
||||
PRTime time = 0;
|
||||
SECStatus rv;
|
||||
SECStatus rvOcsp;
|
||||
OCSPFreshness freshness;
|
||||
|
||||
PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_GetFreshCacheStatus");
|
||||
PKIX_NULLCHECK_THREE(cid, hasFreshStatus, statusIsGood);
|
||||
@ -195,11 +196,11 @@ PKIX_PL_OcspCertID_GetFreshCacheStatus(
|
||||
time = PR_Now();
|
||||
}
|
||||
|
||||
rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
|
||||
rv = ocsp_GetCachedOCSPResponseStatus(
|
||||
cid->certID, time, PR_TRUE, /*ignoreGlobalOcspFailureSetting*/
|
||||
&rvOcsp, missingResponseError);
|
||||
&rvOcsp, missingResponseError, &freshness);
|
||||
|
||||
*hasFreshStatus = (rv == SECSuccess);
|
||||
*hasFreshStatus = (rv == SECSuccess && freshness == ocspFresh);
|
||||
if (*hasFreshStatus) {
|
||||
*statusIsGood = (rvOcsp == SECSuccess);
|
||||
}
|
||||
|
@ -3056,7 +3056,8 @@ nsCycleCollector::Collect(ccType aCCType,
|
||||
// don't want to abandon the current CC, because the graph contains
|
||||
// information about purple roots. So we synchronously finish off
|
||||
// the current CC.
|
||||
void nsCycleCollector::PrepareForGarbageCollection()
|
||||
void
|
||||
nsCycleCollector::PrepareForGarbageCollection()
|
||||
{
|
||||
if (mIncrementalPhase == IdlePhase) {
|
||||
MOZ_ASSERT(mGraph.IsEmpty(), "Non-empty graph when idle");
|
||||
@ -3551,7 +3552,7 @@ nsCycleCollector_collect(nsICycleCollectorListener *aManualListener)
|
||||
}
|
||||
|
||||
void
|
||||
nsCycleCollector_scheduledCollect()
|
||||
nsCycleCollector_scheduledCollect(int64_t aSliceTime)
|
||||
{
|
||||
CollectorData *data = sCollectorData.get();
|
||||
|
||||
@ -3560,8 +3561,13 @@ nsCycleCollector_scheduledCollect()
|
||||
MOZ_ASSERT(data->mCollector);
|
||||
|
||||
PROFILER_LABEL("CC", "nsCycleCollector_scheduledCollect");
|
||||
SliceBudget unlimitedBudget;
|
||||
data->mCollector->Collect(ScheduledCC, unlimitedBudget, nullptr);
|
||||
SliceBudget budget;
|
||||
if (aSliceTime > 0) {
|
||||
budget = SliceBudget::TimeBudget(aSliceTime);
|
||||
} else if (aSliceTime == 0) {
|
||||
budget = SliceBudget::WorkBudget(1);
|
||||
}
|
||||
data->mCollector->Collect(ScheduledCC, budget, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -41,7 +41,11 @@ void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false);
|
||||
bool nsCycleCollector_doDeferredDeletion();
|
||||
|
||||
void nsCycleCollector_collect(nsICycleCollectorListener *aManualListener);
|
||||
void nsCycleCollector_scheduledCollect();
|
||||
|
||||
// If aSliceTime is negative, the CC will run to completion. If aSliceTime
|
||||
// is 0, only a minimum quantum of work will be done. Otherwise, aSliceTime
|
||||
// will be used as the time budget for the slice, in ms.
|
||||
void nsCycleCollector_scheduledCollect(int64_t aSliceTime);
|
||||
|
||||
uint32_t nsCycleCollector_suspectedCount();
|
||||
void nsCycleCollector_shutdown();
|
||||
|
Loading…
x
Reference in New Issue
Block a user