From fef30dfdf50a5d08c55d5072ae124410ad2ecaaa Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Tue, 21 Jun 2011 12:37:03 -0700 Subject: [PATCH 01/19] Bug 665985 - Remove unused pref app.update.nagTimer.restart [r=gavin,mfinkle] --- browser/app/profile/firefox.js | 4 ---- mobile/app/mobile.js | 1 - 2 files changed, 5 deletions(-) diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index cd0cc46aef8..f547006a33a 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -166,10 +166,6 @@ pref("app.update.url", "https://aus3.mozilla.org/update/3/%PRODUCT%/%VERSION%/%B // app.update.interval is in branding section -// Interval: Time before prompting the user again to restart to install the -// latest download (in seconds) default=1 day -pref("app.update.nagTimer.restart", 86400); - // Give the user x seconds to react before showing the big UI. default=12 hours pref("app.update.promptWaitTime", 43200); // Show the Update Checking/Ready UI when the user was idle for x seconds diff --git a/mobile/app/mobile.js b/mobile/app/mobile.js index a943c64d17d..88807cb16b8 100644 --- a/mobile/app/mobile.js +++ b/mobile/app/mobile.js @@ -503,7 +503,6 @@ pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@"); pref("app.update.mode", 1); pref("app.update.silent", false); pref("app.update.url", "https://aus2.mozilla.org/update/4/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PLATFORM_VERSION%/update.xml"); -pref("app.update.nagTimer.restart", 86400); pref("app.update.promptWaitTime", 43200); pref("app.update.idletime", 60); pref("app.update.showInstalledUI", false); From 18150997894966389d8ce88a044d8b791ac09727 Mon Sep 17 00:00:00 2001 From: Steffen Wilberg Date: Tue, 21 Jun 2011 22:23:26 +0200 Subject: [PATCH 02/19] Bug 663253: Remove the 'browser.offline' preference (don't remember offline mode from the previous session). r=gavin --- browser/base/content/browser.js | 4 ---- browser/components/nsBrowserGlue.js | 13 ------------- .../extensions/test/xpinstall/browser_offline.js | 2 -- toolkit/system/dbus/nsDBusService.h | 5 +---- 4 files changed, 1 insertion(+), 23 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index c2ca5bda610..fd973be1205 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5919,10 +5919,6 @@ var BrowserOffline = { } ioService.offline = !ioService.offline; - - // Save the current state for later use as the initial state - // (if there is no netLinkService) - gPrefService.setBoolPref("browser.offline", ioService.offline); }, ///////////////////////////////////////////////////////////////////////////// diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index ccacbf0946e..bdee2a60991 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -350,19 +350,6 @@ BrowserGlue.prototype = { // handle any UI migration this._migrateUI(); - // if ioService is managing the offline status, then ioservice.offline - // is already set correctly. We will continue to allow the ioService - // to manage its offline state until the user uses the "Work Offline" UI. - if (!Services.io.manageOfflineStatus) { - // set the initial state - try { - Services.io.offline = Services.prefs.getBoolPref("browser.offline"); - } - catch (e) { - Services.io.offline = false; - } - } - Services.obs.notifyObservers(null, "browser-ui-startup-complete", ""); }, diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js b/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js index 0ac1692dd7b..6050f24450c 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js @@ -18,7 +18,6 @@ function test() { function download_progress(addon, value, maxValue) { try { Services.io.manageOfflineStatus = false; - Services.prefs.setBoolPref("browser.offline", true); Services.io.offline = true; } catch (ex) { } @@ -37,7 +36,6 @@ function finish_test(count) { is(count, 0, "No add-ons should have been installed"); try { - Services.prefs.setBoolPref("browser.offline", false); Services.io.offline = false; } catch (ex) { } diff --git a/toolkit/system/dbus/nsDBusService.h b/toolkit/system/dbus/nsDBusService.h index 674702c4576..6a0e1ae6480 100644 --- a/toolkit/system/dbus/nsDBusService.h +++ b/toolkit/system/dbus/nsDBusService.h @@ -67,10 +67,7 @@ public: * for NetworkManager state changes; we set nsIOService's offline status to * FALSE when NetworkManager reports NM_STATE_CONNECTED, and to TRUE otherwise. * We also solicit the current status from NetworkManager when this component - * gets loaded. In addition to setting IOService, we also set the - * "browser.offline" preference (because Firefox treats that preference as - * authoritative). We have to wait until prefs have been loaded before setting - * "browser.offline". + * gets loaded. * * In the future we could extend this class to talk to other daemons. * From 7312ab1bf6385476ace4b5c0b9c87744a999ae31 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 21 Jun 2011 16:44:50 -0400 Subject: [PATCH 03/19] Bug 664290. Lower image.mem.min_discard_timeout_ms. r=joe Lowering this value to try to keep our working set smaller. The last choice was arbitrarily large, and we've run into problems with too many images being kept decoded. --HG-- extra : rebase_source : d439284d15e231055b1daed02f5d90e3ad9d7c79 --- modules/libpref/src/init/all.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 89a12dfe769..a505a793d5b 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -3166,7 +3166,11 @@ pref("image.mem.decodeondraw", false); // Minimum timeout for image discarding (in milliseconds). The actual time in // which an image must inactive for it to be discarded will vary between this // value and twice this value. -pref("image.mem.min_discard_timeout_ms", 120000); +// +// This used to be 120 seconds, but having it that high causes our working +// set to grow very large. Switching it back to 10 seconds will hopefully +// be better. +pref("image.mem.min_discard_timeout_ms", 10000); // Chunk size for calls to the image decoders pref("image.mem.decode_bytes_at_a_time", 200000); From dc4e02b76343b13d1135f9dd32184294d08a87b6 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 25 May 2011 14:50:08 -0400 Subject: [PATCH 04/19] Bug 659707. Add -Wdeclaration-after-statement to CFLAGS. r=khuey MSVC doesn't like declarations after statements so we should warn on other platforms too. --- configure.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 0c9592470eb..f577ac0f637 100644 --- a/configure.in +++ b/configure.in @@ -1544,10 +1544,11 @@ if test "$GNU_CC"; then # -Wall - turn on all warnings # -pedantic - make compiler warn about non-ANSI stuff, and # be a little bit stricter + # -Wdeclaration-after-statement - MSVC doesn't like these # Warnings slamm took out for now (these were giving more noise than help): # -Wbad-function-cast - warns when casting a function to a new return type # -Wshadow - removed because it generates more noise than help --pete - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -W -Wno-unused -Wpointer-arith" + _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -W -Wno-unused -Wpointer-arith -Wdeclaration-after-statement" if test -z "$INTEL_CC"; then # Don't use -Wcast-align with ICC case "$CPU_ARCH" in From d00fedc460cb0e4e18b53bf7791556cc59857b03 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 21 Jun 2011 16:48:18 -0400 Subject: [PATCH 05/19] Bug 660662. Remove unnecessary floor in nsNativeTheme::QueueAnimatedContentForRefresh. r=bent Positive numbers are already floored when truncated so this should have no semantic change, and avoids some implicit conversions. --- widget/src/xpwidgets/nsNativeTheme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/xpwidgets/nsNativeTheme.cpp b/widget/src/xpwidgets/nsNativeTheme.cpp index a44e0b8a3aa..ad8f03c02dd 100644 --- a/widget/src/xpwidgets/nsNativeTheme.cpp +++ b/widget/src/xpwidgets/nsNativeTheme.cpp @@ -518,7 +518,7 @@ nsNativeTheme::QueueAnimatedContentForRefresh(nsIContent* aContent, NS_ASSERTION(aMinimumFrameRate <= 1000, "aMinimumFrameRate must be less than 1000!"); - PRUint32 timeout = PRUint32(NS_floor(1000 / aMinimumFrameRate)); + PRUint32 timeout = 1000 / aMinimumFrameRate; timeout = NS_MIN(mAnimatedContentTimeout, timeout); if (!mAnimatedContentTimer) { From 3e900c1912eb673607f311ab2700224dc099c496 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 21 Jun 2011 17:00:47 -0400 Subject: [PATCH 06/19] Bug 548734. Get rid of the footgun ui.use_native_popup_windows preference. r=roc,khuey --- configure.in | 5 +++++ layout/forms/nsComboboxControlFrame.cpp | 6 +++++- mobile/app/mobile.js | 3 --- mobile/confvars.sh | 3 +++ modules/libpref/src/init/all.js | 1 - widget/src/cocoa/nsChildView.mm | 6 +++--- widget/src/cocoa/nsCocoaWindow.mm | 6 +++++- widget/src/cocoa/nsToolkit.mm | 7 ++++--- 8 files changed, 25 insertions(+), 12 deletions(-) diff --git a/configure.in b/configure.in index f577ac0f637..18bd27b7684 100644 --- a/configure.in +++ b/configure.in @@ -4808,6 +4808,7 @@ NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciw USE_ARM_KUSER= BUILD_CTYPES=1 XPC_IDISPATCH_SUPPORT= +MOZ_USE_NATIVE_POPUP_WINDOWS= case "${target}" in @@ -6340,6 +6341,10 @@ for extension in $MOZ_EXTENSIONS; do fi done +if test -n "$MOZ_USE_NATIVE_POPUP_WINDOWS"; then + AC_DEFINE(MOZ_USE_NATIVE_POPUP_WINDOWS) +fi + dnl ======================================================== dnl SVG Display Lists dnl ======================================================== diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 4a582d32369..cc4e4340acd 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1520,6 +1520,10 @@ nsComboboxControlFrame::RestoreState(nsPresState* aState) PRBool nsComboboxControlFrame::ToolkitHasNativePopup() { - return Preferences::GetBool("ui.use_native_popup_windows"); +#ifdef MOZ_USE_NATIVE_POPUP_WINDOWS + return PR_TRUE; +#else + return PR_FALSE; +#endif /* MOZ_USE_NATIVE_POPUP_WINDOWS */ } diff --git a/mobile/app/mobile.js b/mobile/app/mobile.js index 88807cb16b8..50284e5dbdc 100644 --- a/mobile/app/mobile.js +++ b/mobile/app/mobile.js @@ -73,9 +73,6 @@ pref("toolkit.zoomManager.zoomValues", ".2,.3,.5,.67,.8,.9,1,1.1,1.2,1.33,1.5,1. // Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density. pref("browser.viewport.scaleRatio", -1); -/* use custom widget for html:select */ -pref("ui.use_native_popup_windows", true); - /* allow scrollbars to float above chrome ui */ pref("ui.scrollbarsCanOverlapContent", 1); diff --git a/mobile/confvars.sh b/mobile/confvars.sh index a8766a29c2f..fce3e498b8c 100644 --- a/mobile/confvars.sh +++ b/mobile/confvars.sh @@ -60,3 +60,6 @@ fi # Needed for building our components as part of libxul MOZ_APP_COMPONENT_LIBS="browsercomps" MOZ_APP_COMPONENT_INCLUDE=nsBrowserComponents.h + +# use custom widget for html:select +MOZ_USE_NATIVE_POPUP_WINDOWS=1 diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index a505a793d5b..251f4afbf93 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -98,7 +98,6 @@ pref("browser.sessionhistory.max_total_viewers", -1); pref("browser.sessionhistory.optimize_eviction", true); pref("ui.use_native_colors", true); -pref("ui.use_native_popup_windows", false); pref("ui.click_hold_context_menus", false); pref("browser.display.use_document_fonts", 1); // 0 = never, 1 = quick, 2 = always pref("browser.display.use_document_colors", true); diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index 4f3d6dd50ba..833fcd47d9b 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -2955,9 +2955,9 @@ NSEvent* gLastDragMouseDownEvent = nil; if (!gRollupWidget) return; - if (Preferences::GetBool("ui.use_native_popup_windows", PR_FALSE)) { - return; - } +#ifdef MOZ_USE_NATIVE_POPUP_WINDOWS + return; +#endif /* MOZ_USE_NATIVE_POPUP_WINDOWS */ NSWindow *popupWindow = (NSWindow*)gRollupWidget->GetNativeData(NS_NATIVE_WINDOW); if (!popupWindow || ![popupWindow isKindOfClass:[PopupWindow class]]) diff --git a/widget/src/cocoa/nsCocoaWindow.mm b/widget/src/cocoa/nsCocoaWindow.mm index b739c3154d8..111b93c627b 100644 --- a/widget/src/cocoa/nsCocoaWindow.mm +++ b/widget/src/cocoa/nsCocoaWindow.mm @@ -227,7 +227,11 @@ static void FitRectToVisibleAreaForScreen(nsIntRect &aRect, NSScreen *screen) // (native context menus, native tooltips) static PRBool UseNativePopupWindows() { - return Preferences::GetBool("ui.use_native_popup_windows", PR_FALSE); +#ifdef MOZ_USE_NATIVE_POPUP_WINDOWS + return PR_TRUE; +#else + return PR_FALSE; +#endif /* MOZ_USE_NATIVE_POPUP_WINDOWS */ } nsresult nsCocoaWindow::Create(nsIWidget *aParent, diff --git a/widget/src/cocoa/nsToolkit.mm b/widget/src/cocoa/nsToolkit.mm index 9459796adf6..09e29badffd 100644 --- a/widget/src/cocoa/nsToolkit.mm +++ b/widget/src/cocoa/nsToolkit.mm @@ -271,9 +271,10 @@ nsToolkit::RegisterForAllProcessMouseEvents() NS_OBJC_BEGIN_TRY_ABORT_BLOCK; // Don't do this for apps that (like Camino) use native context menus. - if (Preferences::GetBool("ui.use_native_popup_windows", PR_FALSE)) { - return; - } +#ifdef MOZ_USE_NATIVE_POPUP_WINDOWS + return; +#endif /* MOZ_USE_NATIVE_POPUP_WINDOWS */ + if (!mEventMonitorHandler) { EventTypeSpec kEvents[] = {{kEventClassMouse, kEventMouseMoved}}; InstallEventHandler(GetEventMonitorTarget(), EventMonitorHandler, From 7094f522b9a2336b38c5783f4b4039a0a4c0a0e5 Mon Sep 17 00:00:00 2001 From: Taras Glek Date: Tue, 21 Jun 2011 14:39:11 -0700 Subject: [PATCH 07/19] Bug 665805 - Adjust telemetry to work with official metrics server r=Mossop --- modules/libpref/src/init/all.js | 3 +-- toolkit/components/telemetry/TelemetryPing.js | 24 +++++++++++------- .../tests/unit/test_TelemetryPing.js | 25 +++++++++++++------ 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 251f4afbf93..7452142d652 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -272,8 +272,7 @@ pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150); // Telemetry pref("toolkit.telemetry.enabled", false); -// Telemetry test server to be used until the official one is public -pref("toolkit.telemetry.server", "http://telemetry.allizom.org"); +pref("toolkit.telemetry.server", "https://data.mozilla.com"); // view source pref("view_source.syntax_highlight", true); diff --git a/toolkit/components/telemetry/TelemetryPing.js b/toolkit/components/telemetry/TelemetryPing.js index 3885812a89f..46fb70282dd 100644 --- a/toolkit/components/telemetry/TelemetryPing.js +++ b/toolkit/components/telemetry/TelemetryPing.js @@ -97,6 +97,7 @@ function getHistograms() { first = false; retgram.values[r[i - 1]] = 0; } + first = false; last = i + 1; retgram.values[r[i]] = value; } @@ -110,8 +111,9 @@ function getHistograms() { } function generateUUID() { - return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator) - .generateUUID().toString(); + let str = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString(); + // strip {} + return str.substring(1, str.length - 1); } /** @@ -236,9 +238,6 @@ TelemetryPing.prototype = { if (!this._path) this._path = "/submit/telemetry/" + (isTestPing ? reason : generateUUID()); - const TELEMETRY_PING = "telemetry.ping (ms)"; - const TELEMETRY_SUCCESS = "telemetry.success (No, Yes)"; - let hping = Telemetry.getHistogramById("TELEMETRY_PING"); let hsuccess = Telemetry.getHistogramById("TELEMETRY_SUCCESS"); @@ -248,17 +247,24 @@ TelemetryPing.prototype = { request.mozBackgroundRequest = true; request.open("POST", url, true); request.overrideMimeType("text/plain"); + request.setRequestHeader("Content-Type", "application/json"); let startTime = new Date() - function finishRequest(success_metric) { - hsuccess.add(success_metric); + function finishRequest(channel) { + let success = false; + try { + success = channel.QueryInterface(Ci.nsIHttpChannel).requestSucceeded; + } catch(e) { + } + hsuccess.add(success ? 1 : 0); hping.add(new Date() - startTime); if (isTestPing) Services.obs.notifyObservers(null, "telemetry-test-xhr-complete", null); } - request.onerror = function(aEvent) finishRequest(0); - request.onload = function(aEvent) finishRequest(1); + request.onerror = function(aEvent) finishRequest(request.channel); + request.onload = function(aEvent) finishRequest(request.channel); + request.send(nativeJSON.encode(payload)); }, diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js index ceea28e0cb1..28e501c824e 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js @@ -11,7 +11,9 @@ do_load_httpd_js(); Cu.import("resource://gre/modules/Services.jsm"); -const PATH = "/submit/telemetry/test-ping" +const PATH = "/submit/telemetry/test-ping"; +const SERVER = "http://localhost:4444"; + const BinaryInputStream = Components.Constructor( "@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream", @@ -21,7 +23,18 @@ var httpserver = new nsHttpServer(); function telemetry_ping () { let tp = Cc["@mozilla.org/base/telemetry-ping;1"].getService(Ci.nsIObserver); - tp.observe(tp, "test-ping", "http://localhost:4444"); + tp.observe(tp, "test-ping", SERVER); +} + +function nonexistentServerObserver(aSubject, aTopic, aData) { + Services.obs.removeObserver(nonexistentServerObserver, aTopic); + + httpserver.start(4444); + + // Provide a dummy function so it returns 200 instead of 404 to telemetry. + httpserver.registerPathHandler(PATH, function () {}); + Services.obs.addObserver(telemetryObserver, "telemetry-test-xhr-complete", false); + telemetry_ping(); } function telemetryObserver(aSubject, aTopic, aData) { @@ -32,10 +45,7 @@ function telemetryObserver(aSubject, aTopic, aData) { function run_test() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); - httpserver.start(4444); - - Services.obs.addObserver(telemetryObserver, "telemetry-test-xhr-complete", false); - + Services.obs.addObserver(nonexistentServerObserver, "telemetry-test-xhr-complete", false); telemetry_ping(); // spin the event loop do_test_pending(); @@ -55,6 +65,7 @@ function checkHistograms(request, response) { let payload = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON) .decode(readBytesFromInputStream(s)) + do_check_eq(request.getHeader("content-type"), "application/json; charset=UTF-8"); do_check_true(payload.simpleMeasurements.uptime >= 0) // get rid of the non-deterministic field @@ -81,7 +92,7 @@ function checkHistograms(request, response) { range: [1, 2], bucket_count: 3, histogram_type: 2, - values: {0:0, 1:1, 2:0} + values: {0:1, 1:1, 2:0} } let tc = payload.histograms[TELEMETRY_SUCCESS] do_check_eq(uneval(tc), From 41d9f69bd4c9042f7a1538957bccf45a326dd71b Mon Sep 17 00:00:00 2001 From: Taras Glek Date: Tue, 21 Jun 2011 14:39:14 -0700 Subject: [PATCH 08/19] Bug 665805 - Include sums in histograms sent to server r=Mossop --- toolkit/components/telemetry/TelemetryPing.js | 3 ++- toolkit/components/telemetry/tests/unit/test_TelemetryPing.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/toolkit/components/telemetry/TelemetryPing.js b/toolkit/components/telemetry/TelemetryPing.js index 46fb70282dd..9c16c1a5fcc 100644 --- a/toolkit/components/telemetry/TelemetryPing.js +++ b/toolkit/components/telemetry/TelemetryPing.js @@ -82,7 +82,8 @@ function getHistograms() { range: [r[1], r[r.length - 1]], bucket_count: r.length, histogram_type: hgram.histogram_type, - values: {} + values: {}, + sum: hgram.sum }; let first = true; let last = 0; diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js index 28e501c824e..f0734d03bde 100644 --- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js +++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js @@ -92,7 +92,8 @@ function checkHistograms(request, response) { range: [1, 2], bucket_count: 3, histogram_type: 2, - values: {0:1, 1:1, 2:0} + values: {0:1, 1:1, 2:0}, + sum: 1 } let tc = payload.histograms[TELEMETRY_SUCCESS] do_check_eq(uneval(tc), From 6ab0e63563db9c4fec1a394fa7e75666948c2a69 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sun, 22 May 2011 08:23:20 +0200 Subject: [PATCH 09/19] Bug 657297 part 1 - Expose a function to add telemetry samples in XRE. r=tglek,sr=bsmedberg --- toolkit/components/telemetry/Telemetry.cpp | 11 +++++++++++ xpcom/build/nsXULAppAPI.h | 3 +++ 2 files changed, 14 insertions(+) diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index f416ab6e23f..e48060d2ab7 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -50,6 +50,7 @@ #include "nsTHashtable.h" #include "nsHashKeys.h" #include "nsBaseHashtable.h" +#include "nsXULAppAPI.h" namespace { @@ -359,3 +360,13 @@ Accumulate(ID aHistogram, PRUint32 aSample) } // namespace mozilla NSMODULE_DEFN(nsTelemetryModule) = &kTelemetryModule; + +/** + * The XRE_TelemetryAdd function is to be used by embedding applications + * that can't use mozilla::Telemetry::Accumulate() directly. + */ +void +XRE_TelemetryAccumulate(int aID, PRUint32 aSample) +{ + mozilla::Telemetry::Accumulate((mozilla::Telemetry::ID) aID, aSample); +} diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index 887aa92582e..c11ee1a7d87 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -569,4 +569,7 @@ XRE_API(void, XRE_SetupDllBlocklist, ()) #endif +XRE_API(void, + XRE_TelemetryAccumulate, (int aID, PRUint32 aSample)) + #endif // _nsXULAppAPI_h__ From ef186fb5e9b0bb134656cef5723c94cdb15b2a72 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sun, 22 May 2011 08:24:32 +0200 Subject: [PATCH 10/19] Bug 657297 part 2 - Add telemetry samples for initial I/O counters. r=tglek --- browser/app/nsBrowserApp.cpp | 43 +++++++++++++++++-- .../telemetry/TelemetryHistograms.h | 9 ++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp index 78cca4760eb..19da11f9848 100644 --- a/browser/app/nsBrowserApp.cpp +++ b/browser/app/nsBrowserApp.cpp @@ -38,9 +38,12 @@ #include "nsXPCOMGlue.h" #include "nsXULAppAPI.h" -#ifdef XP_WIN +#if defined(XP_WIN) #include #include +#elif defined(XP_UNIX) +#include +#include #endif #include @@ -65,6 +68,8 @@ #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL +#include "mozilla/Telemetry.h" + static void Output(const char *fmt, ... ) { va_list ap; @@ -117,6 +122,7 @@ XRE_FreeAppDataType XRE_FreeAppData; #ifdef XRE_HAS_DLL_BLOCKLIST XRE_SetupDllBlocklistType XRE_SetupDllBlocklist; #endif +XRE_TelemetryAccumulateType XRE_TelemetryAccumulate; XRE_mainType XRE_main; static const nsDynamicFunctionLoad kXULFuncs[] = { @@ -126,6 +132,7 @@ static const nsDynamicFunctionLoad kXULFuncs[] = { #ifdef XRE_HAS_DLL_BLOCKLIST { "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist }, #endif + { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate }, { "XRE_main", (NSFuncPtr*) &XRE_main }, { nsnull, nsnull } }; @@ -209,15 +216,19 @@ int main(int argc, char* argv[]) strcpy(++lastSlash, XPCOM_DLL); -#ifdef XP_WIN + int gotCounters; +#if defined(XP_UNIX) + struct rusage initialRUsage; + gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage); +#elif defined(XP_WIN) // GetProcessIoCounters().ReadOperationCount seems to have little to // do with actual read operations. It reports 0 or 1 at this stage // in the program. Luckily 1 coincides with when prefetch is // enabled. If Windows prefetch didn't happen we can do our own // faster dll preloading. IO_COUNTERS ioCounters; - if (GetProcessIoCounters(GetCurrentProcess(), &ioCounters) - && !ioCounters.ReadOperationCount) + gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters); + if (gotCounters && !ioCounters.ReadOperationCount) #endif { XPCOMGlueEnablePreload(); @@ -240,6 +251,30 @@ int main(int argc, char* argv[]) XRE_SetupDllBlocklist(); #endif + if (gotCounters) { +#if defined(XP_WIN) + XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS, + int(ioCounters.ReadOperationCount)); + XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER, + int(ioCounters.ReadTransferCount / 1024)); + IO_COUNTERS newIoCounters; + if (GetProcessIoCounters(GetCurrentProcess(), &newIoCounters)) { + XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_OPS, + int(newIoCounters.ReadOperationCount - ioCounters.ReadOperationCount)); + XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_TRANSFER, + int((newIoCounters.ReadTransferCount - ioCounters.ReadTransferCount) / 1024)); + } +#elif defined(XP_UNIX) + XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_HARD_FAULTS, + int(initialRUsage.ru_majflt)); + struct rusage newRUsage; + if (!getrusage(RUSAGE_SELF, &newRUsage)) { + XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_HARD_FAULTS, + int(newRUsage.ru_majflt - initialRUsage.ru_majflt)); + } +#endif + } + int result; { ScopedLogging log; diff --git a/toolkit/components/telemetry/TelemetryHistograms.h b/toolkit/components/telemetry/TelemetryHistograms.h index 739e8a28f0a..7238abf0884 100644 --- a/toolkit/components/telemetry/TelemetryHistograms.h +++ b/toolkit/components/telemetry/TelemetryHistograms.h @@ -48,3 +48,12 @@ HISTOGRAM(TELEMETRY_SUCCESS, 0, 1, 2, BOOLEAN, "Success(No, Yes) rate of teleme HISTOGRAM(MEMORY_JS_GC_HEAP, 1024, 512 * 1024, 10, EXPONENTIAL, "Memory(MB) used by the JavaScript GC") HISTOGRAM(MEMORY_RESIDENT, 32 * 1024, 1024 * 1024, 10, EXPONENTIAL, "Resident memory(MB) reported by OS") HISTOGRAM(MEMORY_LAYOUT_ALL, 1024, 64 * 1024, 10, EXPONENTIAL, "Memory(MB) reported used by layout") +#if defined(XP_WIN) +HISTOGRAM(EARLY_GLUESTARTUP_READ_OPS, 1, 100, 12, LINEAR, "ProcessIoCounters.ReadOperationCount before glue startup") +HISTOGRAM(EARLY_GLUESTARTUP_READ_TRANSFER, 1, 50 * 1024, 12, EXPONENTIAL, "ProcessIoCounters.ReadTransferCount before glue startup (KB)") +HISTOGRAM(GLUESTARTUP_READ_OPS, 1, 100, 12, LINEAR, "ProcessIoCounters.ReadOperationCount after glue startup") +HISTOGRAM(GLUESTARTUP_READ_TRANSFER, 1, 50 * 1024, 12, EXPONENTIAL, "ProcessIoCounters.ReadTransferCount after glue startup (KB)") +#elif defined(XP_UNIX) +HISTOGRAM(EARLY_GLUESTARTUP_HARD_FAULTS, 1, 100, 12, LINEAR, "Hard faults count before glue startup") +HISTOGRAM(GLUESTARTUP_HARD_FAULTS, 1, 500, 12, EXPONENTIAL, "Hard faults count after glue startup") +#endif From 2762282cb3888198c13b0a869ae19aab3f99d584 Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Wed, 22 Jun 2011 10:12:35 +0900 Subject: [PATCH 11/19] Bug 663288 - Don't allow instance times to be self-dependent, r=dholbert --- content/smil/nsSMILInstanceTime.cpp | 32 +++++------ content/smil/nsSMILInstanceTime.h | 2 +- content/smil/nsSMILInterval.cpp | 9 +++ content/smil/nsSMILTimedElement.cpp | 37 +++++++++--- content/smil/nsSMILTimedElement.h | 4 ++ .../svg/smil/syncbase/cycle-self-ref-4.svg | 32 +++++++++++ .../svg/smil/syncbase/cycle-self-ref-5.svg | 56 +++++++++++++++++++ .../reftests/svg/smil/syncbase/reftest.list | 2 + 8 files changed, 148 insertions(+), 26 deletions(-) create mode 100644 layout/reftests/svg/smil/syncbase/cycle-self-ref-4.svg create mode 100644 layout/reftests/svg/smil/syncbase/cycle-self-ref-5.svg diff --git a/content/smil/nsSMILInstanceTime.cpp b/content/smil/nsSMILInstanceTime.cpp index c9f870b9438..656a0396c63 100644 --- a/content/smil/nsSMILInstanceTime.cpp +++ b/content/smil/nsSMILInstanceTime.cpp @@ -228,6 +228,22 @@ nsSMILInstanceTime::IsDependentOn(const nsSMILInstanceTime& aOther) const return myBaseTime->IsDependentOn(aOther); } +const nsSMILInstanceTime* +nsSMILInstanceTime::GetBaseTime() const +{ + if (!mBaseInterval) { + return nsnull; + } + + NS_ABORT_IF_FALSE(mCreator, "Base interval is set but there is no creator."); + if (!mCreator) { + return nsnull; + } + + return mCreator->DependsOnBegin() ? mBaseInterval->Begin() : + mBaseInterval->End(); +} + void nsSMILInstanceTime::SetBaseInterval(nsSMILInterval* aBaseInterval) { @@ -246,19 +262,3 @@ nsSMILInstanceTime::SetBaseInterval(nsSMILInterval* aBaseInterval) mBaseInterval = aBaseInterval; } - -const nsSMILInstanceTime* -nsSMILInstanceTime::GetBaseTime() const -{ - if (!mBaseInterval) { - return nsnull; - } - - NS_ABORT_IF_FALSE(mCreator, "Base interval is set but there is no creator."); - if (!mCreator) { - return nsnull; - } - - return mCreator->DependsOnBegin() ? mBaseInterval->Begin() : - mBaseInterval->End(); -} diff --git a/content/smil/nsSMILInstanceTime.h b/content/smil/nsSMILInstanceTime.h index 531cb4d6636..3f21bfeba8e 100644 --- a/content/smil/nsSMILInstanceTime.h +++ b/content/smil/nsSMILInstanceTime.h @@ -117,6 +117,7 @@ public: PRBool IsDependent() const { return !!mBaseInterval; } PRBool IsDependentOn(const nsSMILInstanceTime& aOther) const; const nsSMILInterval* GetBaseInterval() const { return mBaseInterval; } + const nsSMILInstanceTime* GetBaseTime() const; PRBool SameTimeAndBase(const nsSMILInstanceTime& aOther) const { @@ -132,7 +133,6 @@ public: protected: void SetBaseInterval(nsSMILInterval* aBaseInterval); - const nsSMILInstanceTime* GetBaseTime() const; nsSMILTimeValue mTime; diff --git a/content/smil/nsSMILInterval.cpp b/content/smil/nsSMILInterval.cpp index 8a2c7b10448..bc92760125a 100644 --- a/content/smil/nsSMILInterval.cpp +++ b/content/smil/nsSMILInterval.cpp @@ -114,6 +114,11 @@ nsSMILInterval::SetBegin(nsSMILInstanceTime& aBegin) "Attempting to set unresolved begin time on interval"); NS_ABORT_IF_FALSE(!mBeginFixed, "Attempting to set begin time but the begin point is fixed"); + // Check that we're not making an instance time dependent on itself. Such an + // arrangement does not make intuitive sense and should be detected when + // creating or updating intervals. + NS_ABORT_IF_FALSE(!mBegin || aBegin.GetBaseTime() != mBegin, + "Attempting to make self-dependent instance time"); mBegin = &aBegin; } @@ -123,6 +128,10 @@ nsSMILInterval::SetEnd(nsSMILInstanceTime& aEnd) { NS_ABORT_IF_FALSE(!mEndFixed, "Attempting to set end time but the end point is fixed"); + // As with SetBegin, check we're not making an instance time dependent on + // itself. + NS_ABORT_IF_FALSE(!mEnd || aEnd.GetBaseTime() != mEnd, + "Attempting to make self-dependent instance time"); mEnd = &aEnd; } diff --git a/content/smil/nsSMILTimedElement.cpp b/content/smil/nsSMILTimedElement.cpp index c8cb3921281..58acb8f882c 100644 --- a/content/smil/nsSMILTimedElement.cpp +++ b/content/smil/nsSMILTimedElement.cpp @@ -511,7 +511,7 @@ nsSMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, PRBool aEndOnly) case STATE_STARTUP: { nsSMILInterval firstInterval; - mElementState = GetNextInterval(nsnull, nsnull, firstInterval) + mElementState = GetNextInterval(nsnull, nsnull, nsnull, firstInterval) ? STATE_WAITING : STATE_POSTACTIVE; stateChanged = PR_TRUE; @@ -558,7 +558,8 @@ nsSMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, PRBool aEndOnly) if (mCurrentInterval->End()->Time() <= sampleTime) { nsSMILInterval newInterval; - mElementState = GetNextInterval(mCurrentInterval, nsnull, newInterval) + mElementState = + GetNextInterval(mCurrentInterval, nsnull, nsnull, newInterval) ? STATE_WAITING : STATE_POSTACTIVE; if (mClient) { @@ -1497,6 +1498,7 @@ nsSMILTimedElement::FilterInstanceTimes(InstanceTimeList& aList) // PRBool nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval, + const nsSMILInterval* aReplacedInterval, const nsSMILInstanceTime* aFixedBeginTime, nsSMILInterval& aResult) const { @@ -1539,19 +1541,35 @@ nsSMILTimedElement::GetNextInterval(const nsSMILInterval* aPrevInterval, tempBegin = new nsSMILInstanceTime(nsSMILTimeValue(0)); } else { PRInt32 beginPos = 0; - tempBegin = GetNextGreaterOrEqual(mBeginInstances, beginAfter, beginPos); - if (!tempBegin || !tempBegin->Time().IsResolved()) { - return PR_FALSE; - } + // If we're updating the current interval then skip any begin time that is + // dependent on the current interval's begin time. e.g. + // Time().IsResolved()) { + return PR_FALSE; + } + } while (aReplacedInterval && + tempBegin->GetBaseTime() == aReplacedInterval->Begin()); } - NS_ABORT_IF_FALSE(tempBegin && tempBegin->Time().IsResolved() && + NS_ABORT_IF_FALSE(tempBegin && tempBegin->Time().IsResolved() && tempBegin->Time() >= beginAfter, "Got a bad begin time while fetching next interval"); // Calculate end time { PRInt32 endPos = 0; - tempEnd = GetNextGreaterOrEqual(mEndInstances, tempBegin->Time(), endPos); + // As above with begin times, avoid creating self-referential loops + // between instance times by checking that the newly found end instance + // time is not already dependent on the end of the current interval. + do { + tempEnd = + GetNextGreaterOrEqual(mEndInstances, tempBegin->Time(), endPos); + } while (tempEnd && aReplacedInterval && + tempEnd->GetBaseTime() == aReplacedInterval->End()); // If the last interval ended at the same point and was zero-duration and // this one is too, look for another end to use instead @@ -1817,7 +1835,8 @@ nsSMILTimedElement::UpdateCurrentInterval(PRBool aForceChangeNotice) ? mCurrentInterval->Begin() : nsnull; nsSMILInterval updatedInterval; - if (GetNextInterval(GetPreviousInterval(), beginTime, updatedInterval)) { + if (GetNextInterval(GetPreviousInterval(), mCurrentInterval, + beginTime, updatedInterval)) { if (mElementState == STATE_POSTACTIVE) { diff --git a/content/smil/nsSMILTimedElement.h b/content/smil/nsSMILTimedElement.h index 25774e3d3e9..d14273a621b 100644 --- a/content/smil/nsSMILTimedElement.h +++ b/content/smil/nsSMILTimedElement.h @@ -472,6 +472,9 @@ protected: * @param aPrevInterval The previous interval used. If supplied, the first * interval that begins after aPrevInterval will be * returned. May be nsnull. + * @param aReplacedInterval The interval that is being updated (if any). This + * used to ensure we don't return interval endpoints + * that are dependent on themselves. May be nsnull. * @param aFixedBeginTime The time to use for the start of the interval. This * is used when only the endpoint of the interval * should be updated such as when the animation is in @@ -482,6 +485,7 @@ protected: * @return PR_TRUE if a suitable interval was found, PR_FALSE otherwise. */ PRBool GetNextInterval(const nsSMILInterval* aPrevInterval, + const nsSMILInterval* aReplacedInterval, const nsSMILInstanceTime* aFixedBeginTime, nsSMILInterval& aResult) const; nsSMILInstanceTime* GetNextGreater(const InstanceTimeList& aList, diff --git a/layout/reftests/svg/smil/syncbase/cycle-self-ref-4.svg b/layout/reftests/svg/smil/syncbase/cycle-self-ref-4.svg new file mode 100644 index 00000000000..c53b3c5fa78 --- /dev/null +++ b/layout/reftests/svg/smil/syncbase/cycle-self-ref-4.svg @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/layout/reftests/svg/smil/syncbase/cycle-self-ref-5.svg b/layout/reftests/svg/smil/syncbase/cycle-self-ref-5.svg new file mode 100644 index 00000000000..e0e36e152ac --- /dev/null +++ b/layout/reftests/svg/smil/syncbase/cycle-self-ref-5.svg @@ -0,0 +1,56 @@ + + + + + + + + + + diff --git a/layout/reftests/svg/smil/syncbase/reftest.list b/layout/reftests/svg/smil/syncbase/reftest.list index 0430c3b1423..52258e782fc 100644 --- a/layout/reftests/svg/smil/syncbase/reftest.list +++ b/layout/reftests/svg/smil/syncbase/reftest.list @@ -64,6 +64,8 @@ == cycle-self-ref-1.svg green-box-ref.svg == cycle-self-ref-2.svg green-box-ref.svg == cycle-self-ref-3.svg green-box-ref.svg +== cycle-self-ref-4.svg green-box-ref.svg +== cycle-self-ref-5.svg green-box-ref.svg == cycle-invalid-1.svg green-box-ref.svg == cycle-invalid-2.svg green-box-ref.svg == cycle-invalid-3.svg green-box-ref.svg From ed0e66fb0b06010b97e155d691d46c7b72782064 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Wed, 15 Jun 2011 02:14:33 +0200 Subject: [PATCH 12/19] Bug 664340 - Fallback to c++ when CXX is not set. r=khuey --- build/autoconf/libstdcxx.py | 2 +- configure.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/autoconf/libstdcxx.py b/build/autoconf/libstdcxx.py index 35008918e6d..cc4ecb67893 100755 --- a/build/autoconf/libstdcxx.py +++ b/build/autoconf/libstdcxx.py @@ -67,7 +67,7 @@ def find_version(e): return encode_ver(last_version) if __name__ == '__main__': - cxx_env = os.environ['CXX'] + cxx_env = os.environ.get('CXX', 'c++') print 'MOZ_LIBSTDCXX_TARGET_VERSION=%s' % find_version(cxx_env) host_cxx_env = os.environ.get('HOST_CXX', cxx_env) print 'MOZ_LIBSTDCXX_HOST_VERSION=%s' % find_version(host_cxx_env) diff --git a/configure.in b/configure.in index 18bd27b7684..eeee45533fb 100644 --- a/configure.in +++ b/configure.in @@ -7672,7 +7672,7 @@ MOZ_ARG_ENABLE_BOOL(stdcxx-compat, AC_SUBST(STDCXX_COMPAT) if test -n "$STDCXX_COMPAT"; then - eval $($_topsrcdir/build/autoconf/libstdcxx.py) + eval $($PYTHON $_topsrcdir/build/autoconf/libstdcxx.py) AC_SUBST(MOZ_LIBSTDCXX_TARGET_VERSION) AC_SUBST(MOZ_LIBSTDCXX_HOST_VERSION) fi From ea532fc8afabba2e6e28558c546554d60ecec62a Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Tue, 21 Jun 2011 21:44:00 -0700 Subject: [PATCH 13/19] Followup to bug 661973: Fix bug with COM outparams and add convenience operators. r=cjones --- mfbt/RefPtr.h | 55 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/mfbt/RefPtr.h b/mfbt/RefPtr.h index 0b6fa60db27..3c9be7ff8af 100644 --- a/mfbt/RefPtr.h +++ b/mfbt/RefPtr.h @@ -131,6 +131,8 @@ class RefPtr friend class TemporaryRef; friend class OutParamRef; + struct dontRef {}; + public: RefPtr() : ptr(0) { } RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {} @@ -164,13 +166,15 @@ public: TemporaryRef forget() { T* tmp = ptr; ptr = 0; - return TemporaryRef(tmp); + return TemporaryRef(tmp, dontRef()); } T* get() const { return ptr; } operator T*() const { return ptr; } T* operator->() const { return ptr; } T& operator*() const { return *ptr; } + template + operator TemporaryRef() { return forget(); } private: void assign(T* t) { @@ -206,7 +210,10 @@ class TemporaryRef // To allow it to construct TemporaryRef from a bare T* friend class RefPtr; + typedef typename RefPtr::dontRef dontRef; + public: + TemporaryRef(T* t) : ptr(RefPtr::ref(t)) {} TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {} template @@ -221,7 +228,7 @@ public: } private: - TemporaryRef(T* t) : ptr(t) {} + TemporaryRef(T* t, const dontRef&) : ptr(t) {} mutable T* ptr; @@ -231,10 +238,13 @@ private: /** * OutParamRef is a wrapper that tracks a refcounted pointer passed as - * an outparam argument to a function. If OutParamRef holds a ref to - * an object that's reassigned during a function call in which the - * OutParamRef is an outparam, then the old object is unref'd and the - * new object is ref'd. + * an outparam argument to a function. OutParamRef implements COM T** + * outparam semantics: this requires the callee to AddRef() the T* + * returned through the T** outparam on behalf of the caller. This + * means the caller (through OutParamRef) must Release() the old + * object contained in the tracked RefPtr. It's OK if the callee + * returns the same T* passed to it through the T** outparam, as long + * as the callee obeys the COM discipline. * * Prefer returning TemporaryRef from functions over creating T** * outparams and passing OutParamRef to T**. Prefer RefPtr* @@ -246,7 +256,10 @@ class OutParamRef friend OutParamRef byRef(RefPtr&); public: - ~OutParamRef() { refPtr = tmp; } + ~OutParamRef() { + RefPtr::unref(refPtr.ptr); + refPtr.ptr = tmp; + } operator T**() { return &tmp; } @@ -260,6 +273,9 @@ private: OutParamRef& operator=(const OutParamRef&); }; +/** + * byRef cooperates with OutParamRef to implement COM outparam semantics. + */ template OutParamRef byRef(RefPtr& ptr) @@ -299,26 +315,29 @@ struct Bar : public Foo { }; TemporaryRef NewFoo() { - RefPtr f = new Foo(); - return f.forget(); + return RefPtr(new Foo()); } TemporaryRef NewBar() { - RefPtr b = new Bar(); - return b.forget(); + return new Bar(); } void GetNewFoo(Foo** f) { *f = new Bar(); + // Kids, don't try this at home + (*f)->AddRef(); } void GetPassedFoo(Foo** f) -{} +{ + // Kids, don't try this at home + (*f)->AddRef(); +} void GetNewFoo(RefPtr* f) @@ -330,6 +349,12 @@ void GetPassedFoo(RefPtr* f) {} +TemporaryRef +GetNullFoo() +{ + return 0; +} + int main(int argc, char** argv) { @@ -407,6 +432,12 @@ main(int argc, char** argv) } MOZ_ASSERT(13 == Foo::numDestroyed); + { + RefPtr f = GetNullFoo(); + MOZ_ASSERT(13 == Foo::numDestroyed); + } + MOZ_ASSERT(13 == Foo::numDestroyed); + return 0; } From ca3af8eefccf28d4173a8dfe4ef938d5dec14df6 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Wed, 22 Jun 2011 15:39:10 +0900 Subject: [PATCH 14/19] Bug 664917 Add Preferences API for getting default pref values r=roc, feedback=bz --- modules/libpref/public/Preferences.h | 100 ++++++++++++++- modules/libpref/src/Preferences.cpp | 182 ++++++++++++++++++++++----- 2 files changed, 248 insertions(+), 34 deletions(-) diff --git a/modules/libpref/public/Preferences.h b/modules/libpref/public/Preferences.h index b23a87bb793..d36fc0a3f68 100644 --- a/modules/libpref/public/Preferences.h +++ b/modules/libpref/public/Preferences.h @@ -74,8 +74,8 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIPREFSERVICE NS_DECL_NSIPREFSERVICEINTERNAL - NS_FORWARD_NSIPREFBRANCH(mRootBranch->) - NS_FORWARD_NSIPREFBRANCH2(mRootBranch->) + NS_FORWARD_NSIPREFBRANCH(sRootBranch->) + NS_FORWARD_NSIPREFBRANCH2(sRootBranch->) NS_DECL_NSIOBSERVER Preferences(); @@ -110,7 +110,17 @@ public: static nsIPrefBranch2* GetRootBranch() { NS_ENSURE_TRUE(InitStaticMembers(), nsnull); - return sPreferences->mRootBranch.get(); + return sRootBranch; + } + + /** + * Returns shared default pref branch instance. + * NOTE: not addreffed. + */ + static nsIPrefBranch* GetDefaultRootBranch() + { + NS_ENSURE_TRUE(InitStaticMembers(), nsnull); + return sDefaultRootBranch; } /** @@ -138,6 +148,27 @@ public: return result; } + /** + * Gets char type pref value directly. If failed, the get() of result + * returns NULL. Even if succeeded but the result was empty string, the + * get() does NOT return NULL. So, you can check whether the method + * succeeded or not by: + * + * nsAdoptingString value = Prefereces::GetString("foo.bar"); + * if (!value) { + * // failed + * } + * + * Be aware. If you wrote as: + * + * nsAutoString value = Preferences::GetString("foo.bar"); + * if (!value.get()) { + * // the condition is always FALSE!! + * } + * + * The value.get() doesn't return NULL. You must use nsAdoptingString when + * you need to check whether it was failure or not. + */ static nsAdoptingCString GetCString(const char* aPref); static nsAdoptingString GetString(const char* aPref); static nsAdoptingCString GetLocalizedCString(const char* aPref); @@ -251,6 +282,65 @@ public: const char* aPref, PRUint32 aDefault = 0); + /** + * Gets the default bool, int or uint value of the pref. + * The result is raw result of nsIPrefBranch::Get*Pref(). + * If the pref could have any value, you needed to use these methods. + * If not so, you could use below methods. + */ + static nsresult GetDefaultBool(const char* aPref, PRBool* aResult); + static nsresult GetDefaultInt(const char* aPref, PRInt32* aResult); + static nsresult GetDefaultUint(const char* aPref, PRUint32* aResult) + { + return GetDefaultInt(aPref, reinterpret_cast(aResult)); + } + + /** + * Gets the default bool, int or uint value of the pref directly. + * You can set an invalid value of the pref to aFailedResult. If these + * methods failed to get the default value, they would return the + * aFailedResult value. + */ + static PRBool GetDefaultBool(const char* aPref, PRBool aFailedResult) + { + PRBool result; + return NS_SUCCEEDED(GetDefaultBool(aPref, &result)) ? result : + aFailedResult; + } + static PRInt32 GetDefaultInt(const char* aPref, PRInt32 aFailedResult) + { + PRInt32 result; + return NS_SUCCEEDED(GetDefaultInt(aPref, &result)) ? result : aFailedResult; + } + static PRUint32 GetDefaultUint(const char* aPref, PRUint32 aFailedResult) + { + return static_cast( + GetDefaultInt(aPref, static_cast(aFailedResult))); + } + + /** + * Gets the default value of the char type pref. + * If the get() of the result returned NULL, that meant the value didn't + * have default value. + * + * See the comment at definition at GetString() and GetCString() for more + * details of the result. + */ + static nsAdoptingString GetDefaultString(const char* aPref); + static nsAdoptingCString GetDefaultCString(const char* aPref); + static nsAdoptingString GetDefaultLocalizedString(const char* aPref); + static nsAdoptingCString GetDefaultLocalizedCString(const char* aPref); + + static nsresult GetDefaultCString(const char* aPref, nsACString* aResult); + static nsresult GetDefaultString(const char* aPref, nsAString* aResult); + static nsresult GetDefaultLocalizedCString(const char* aPref, + nsACString* aResult); + static nsresult GetDefaultLocalizedString(const char* aPref, + nsAString* aResult); + + static nsresult GetDefaultComplex(const char* aPref, const nsIID &aType, + void** aResult); + protected: nsresult NotifyServiceObservers(const char *aSubject); nsresult UseDefaultPrefFile(); @@ -262,10 +352,12 @@ protected: nsresult MakeBackupPrefFile(nsIFile *aFile); private: - nsCOMPtr mRootBranch; nsCOMPtr mCurrentFile; static Preferences* sPreferences; + static nsIPrefBranch2* sRootBranch; + // NOTE: default branch doesn't return nsIPrefBranch2 interface at query. + static nsIPrefBranch* sDefaultRootBranch; static PRBool sShutdown; /** diff --git a/modules/libpref/src/Preferences.cpp b/modules/libpref/src/Preferences.cpp index 0e966c486bc..37cd6198f33 100644 --- a/modules/libpref/src/Preferences.cpp +++ b/modules/libpref/src/Preferences.cpp @@ -88,6 +88,8 @@ static nsresult pref_InitInitialObjects(void); static nsresult pref_LoadPrefsInDirList(const char *listId); Preferences* Preferences::sPreferences = nsnull; +nsIPrefBranch2* Preferences::sRootBranch = nsnull; +nsIPrefBranch* Preferences::sDefaultRootBranch = nsnull; PRBool Preferences::sShutdown = PR_FALSE; class ValueObserverHashKey : public PLDHashEntryHdr { @@ -223,9 +225,16 @@ Preferences::InitStaticMembers(PRBool aForService) return sPreferences != nsnull; } + sRootBranch = new nsPrefBranch("", PR_FALSE); + NS_ADDREF(sRootBranch); + sDefaultRootBranch = new nsPrefBranch("", PR_TRUE); + NS_ADDREF(sDefaultRootBranch); + sPreferences = new Preferences(); NS_ADDREF(sPreferences); - if (NS_FAILED(sPreferences->Init()) || !sPreferences->mRootBranch) { + + if (NS_FAILED(sPreferences->Init())) { + // The singleton instance will delete sRootBranch and sDefaultRootBranch. NS_RELEASE(sPreferences); return PR_FALSE; } @@ -274,6 +283,9 @@ Preferences::~Preferences() delete gCacheData; gCacheData = nsnull; + NS_RELEASE(sRootBranch); + NS_RELEASE(sDefaultRootBranch); + sPreferences = nsnull; PREF_Cleanup(); @@ -306,12 +318,6 @@ NS_INTERFACE_MAP_END nsresult Preferences::Init() { - nsPrefBranch *rootBranch = new nsPrefBranch("", PR_FALSE); - if (!rootBranch) - return NS_ERROR_OUT_OF_MEMORY; - - mRootBranch = (nsIPrefBranch2 *)rootBranch; - nsresult rv; rv = PREF_Init(); @@ -342,7 +348,7 @@ Preferences::Init() * category which will do the rest. */ - rv = mRootBranch->GetCharPref("general.config.filename", getter_Copies(lockFileName)); + rv = sRootBranch->GetCharPref("general.config.filename", getter_Copies(lockFileName)); if (NS_SUCCEEDED(rv)) NS_CreateServicesFromCategory("pref-config-startup", static_cast(static_cast(this)), @@ -563,7 +569,7 @@ Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval) rv = CallQueryInterface(prefBranch, _retval); } else { // special case caching the default root - rv = CallQueryInterface(mRootBranch, _retval); + rv = CallQueryInterface(sRootBranch, _retval); } return rv; } @@ -571,15 +577,16 @@ Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval) NS_IMETHODIMP Preferences::GetDefaultBranch(const char *aPrefRoot, nsIPrefBranch **_retval) { - nsresult rv; + if (!aPrefRoot || !aPrefRoot[0]) { + return CallQueryInterface(sDefaultRootBranch, _retval); + } // TODO: - cache this stuff and allow consumers to share branches (hold weak references I think) nsPrefBranch* prefBranch = new nsPrefBranch(aPrefRoot, PR_TRUE); if (!prefBranch) return NS_ERROR_OUT_OF_MEMORY; - rv = CallQueryInterface(prefBranch, _retval); - return rv; + return CallQueryInterface(prefBranch, _retval); } @@ -1144,7 +1151,7 @@ Preferences::GetBool(const char* aPref, PRBool* aResult) { NS_PRECONDITION(aResult, "aResult must not be NULL"); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->GetBoolPref(aPref, aResult); + return sRootBranch->GetBoolPref(aPref, aResult); } // static @@ -1153,7 +1160,7 @@ Preferences::GetInt(const char* aPref, PRInt32* aResult) { NS_PRECONDITION(aResult, "aResult must not be NULL"); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->GetIntPref(aPref, aResult); + return sRootBranch->GetIntPref(aPref, aResult); } // static @@ -1181,8 +1188,7 @@ Preferences::GetCString(const char* aPref, nsACString* aResult) NS_PRECONDITION(aResult, "aResult must not be NULL"); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); nsCAutoString result; - nsresult rv = - sPreferences->mRootBranch->GetCharPref(aPref, getter_Copies(result)); + nsresult rv = sRootBranch->GetCharPref(aPref, getter_Copies(result)); if (NS_SUCCEEDED(rv)) { *aResult = result; } @@ -1196,8 +1202,7 @@ Preferences::GetString(const char* aPref, nsAString* aResult) NS_PRECONDITION(aResult, "aResult must not be NULL"); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); nsCAutoString result; - nsresult rv = - sPreferences->mRootBranch->GetCharPref(aPref, getter_Copies(result)); + nsresult rv = sRootBranch->GetCharPref(aPref, getter_Copies(result)); if (NS_SUCCEEDED(rv)) { CopyUTF8toUTF16(result, *aResult); } @@ -1242,7 +1247,7 @@ Preferences::GetLocalizedString(const char* aPref, nsAString* aResult) NS_PRECONDITION(aResult, "aResult must not be NULL"); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); nsCOMPtr prefLocalString; - nsresult rv = sPreferences->mRootBranch->GetComplexValue(aPref, + nsresult rv = sRootBranch->GetComplexValue(aPref, NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(prefLocalString)); if (NS_SUCCEEDED(rv)) { @@ -1257,7 +1262,7 @@ nsresult Preferences::GetComplex(const char* aPref, const nsIID &aType, void** aResult) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->GetComplexValue(aPref, aType, aResult); + return sRootBranch->GetComplexValue(aPref, aType, aResult); } // static @@ -1265,7 +1270,7 @@ nsresult Preferences::SetCString(const char* aPref, const char* aValue) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->SetCharPref(aPref, aValue); + return sRootBranch->SetCharPref(aPref, aValue); } // static @@ -1296,7 +1301,7 @@ nsresult Preferences::SetBool(const char* aPref, PRBool aValue) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->SetBoolPref(aPref, aValue); + return sRootBranch->SetBoolPref(aPref, aValue); } // static @@ -1304,7 +1309,7 @@ nsresult Preferences::SetInt(const char* aPref, PRInt32 aValue) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->SetIntPref(aPref, aValue); + return sRootBranch->SetIntPref(aPref, aValue); } // static @@ -1313,7 +1318,7 @@ Preferences::SetComplex(const char* aPref, const nsIID &aType, nsISupports* aValue) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->SetComplexValue(aPref, aType, aValue); + return sRootBranch->SetComplexValue(aPref, aType, aValue); } // static @@ -1321,7 +1326,7 @@ nsresult Preferences::ClearUser(const char* aPref) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->ClearUserPref(aPref); + return sRootBranch->ClearUserPref(aPref); } // static @@ -1330,8 +1335,7 @@ Preferences::HasUserValue(const char* aPref) { NS_ENSURE_TRUE(InitStaticMembers(), PR_FALSE); PRBool hasUserValue; - nsresult rv = - sPreferences->mRootBranch->PrefHasUserValue(aPref, &hasUserValue); + nsresult rv = sRootBranch->PrefHasUserValue(aPref, &hasUserValue); if (NS_FAILED(rv)) { return PR_FALSE; } @@ -1344,7 +1348,7 @@ Preferences::AddStrongObserver(nsIObserver* aObserver, const char* aPref) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->AddObserver(aPref, aObserver, PR_FALSE); + return sRootBranch->AddObserver(aPref, aObserver, PR_FALSE); } // static @@ -1353,7 +1357,7 @@ Preferences::AddWeakObserver(nsIObserver* aObserver, const char* aPref) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->AddObserver(aPref, aObserver, PR_TRUE); + return sRootBranch->AddObserver(aPref, aObserver, PR_TRUE); } // static @@ -1365,7 +1369,7 @@ Preferences::RemoveObserver(nsIObserver* aObserver, return NS_OK; // Observers have been released automatically. } NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE); - return sPreferences->mRootBranch->RemoveObserver(aPref, aObserver); + return sRootBranch->RemoveObserver(aPref, aObserver); } // static @@ -1528,4 +1532,122 @@ Preferences::AddUintVarCache(PRUint32* aCache, return RegisterCallback(UintVarChanged, aPref, data); } +// static +nsresult +Preferences::GetDefaultBool(const char* aPref, PRBool* aResult) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sDefaultRootBranch->GetBoolPref(aPref, aResult); +} + +// static +nsresult +Preferences::GetDefaultInt(const char* aPref, PRInt32* aResult) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sDefaultRootBranch->GetIntPref(aPref, aResult); +} + +// static +nsresult +Preferences::GetDefaultCString(const char* aPref, nsACString* aResult) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsCAutoString result; + nsresult rv = sDefaultRootBranch->GetCharPref(aPref, getter_Copies(result)); + if (NS_SUCCEEDED(rv)) { + *aResult = result; + } + return rv; +} + +// static +nsresult +Preferences::GetDefaultString(const char* aPref, nsAString* aResult) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsCAutoString result; + nsresult rv = sDefaultRootBranch->GetCharPref(aPref, getter_Copies(result)); + if (NS_SUCCEEDED(rv)) { + CopyUTF8toUTF16(result, *aResult); + } + return rv; +} + +// static +nsresult +Preferences::GetDefaultLocalizedCString(const char* aPref, + nsACString* aResult) +{ + nsAutoString result; + nsresult rv = GetDefaultLocalizedString(aPref, &result); + if (NS_SUCCEEDED(rv)) { + CopyUTF16toUTF8(result, *aResult); + } + return rv; +} + +// static +nsresult +Preferences::GetDefaultLocalizedString(const char* aPref, + nsAString* aResult) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsCOMPtr prefLocalString; + nsresult rv = + sDefaultRootBranch->GetComplexValue(aPref, + NS_GET_IID(nsIPrefLocalizedString), + getter_AddRefs(prefLocalString)); + if (NS_SUCCEEDED(rv)) { + NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL"); + prefLocalString->GetData(getter_Copies(*aResult)); + } + return rv; +} + +// static +nsAdoptingString +Preferences::GetDefaultString(const char* aPref) +{ + nsAdoptingString result; + GetDefaultString(aPref, &result); + return result; +} + +// static +nsAdoptingCString +Preferences::GetDefaultCString(const char* aPref) +{ + nsAdoptingCString result; + GetDefaultCString(aPref, &result); + return result; +} + +// static +nsAdoptingString +Preferences::GetDefaultLocalizedString(const char* aPref) +{ + nsAdoptingString result; + GetDefaultLocalizedString(aPref, &result); + return result; +} + +// static +nsAdoptingCString +Preferences::GetDefaultLocalizedCString(const char* aPref) +{ + nsAdoptingCString result; + GetDefaultLocalizedCString(aPref, &result); + return result; +} + +// static +nsresult +Preferences::GetDefaultComplex(const char* aPref, const nsIID &aType, + void** aResult) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sDefaultRootBranch->GetComplexValue(aPref, aType, aResult); +} + } // namespace mozilla From 253f894c83c4c8b9e7342b4ad5219d3a61dda253 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Wed, 22 Jun 2011 16:33:30 +0900 Subject: [PATCH 15/19] Bug 182279 - select.add() should have the second parameter optional. r=smaug --- content/html/content/test/Makefile.in | 1 + content/html/content/test/test_bug182279.html | 36 +++++++++++++++++++ .../html/nsIDOMHTMLSelectElement.idl | 4 +-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 content/html/content/test/test_bug182279.html diff --git a/content/html/content/test/Makefile.in b/content/html/content/test/Makefile.in index 4f7eb647dee..f3183c33f76 100644 --- a/content/html/content/test/Makefile.in +++ b/content/html/content/test/Makefile.in @@ -80,6 +80,7 @@ _TEST_FILES = \ test_bug109445.html \ test_bug109445.xhtml \ test_bug143220.html \ + test_bug182279.html \ test_bug237071.html \ bug242709_iframe.html \ bug242709_load.html \ diff --git a/content/html/content/test/test_bug182279.html b/content/html/content/test/test_bug182279.html new file mode 100644 index 00000000000..58a1c9c8f89 --- /dev/null +++ b/content/html/content/test/test_bug182279.html @@ -0,0 +1,36 @@ + + + + + Test for Bug 182279 + + + + + +Moozilla Bug 182279 +

+ +
+
+
+ + diff --git a/dom/interfaces/html/nsIDOMHTMLSelectElement.idl b/dom/interfaces/html/nsIDOMHTMLSelectElement.idl index 5ae36c7ca4e..c87b3b269ee 100644 --- a/dom/interfaces/html/nsIDOMHTMLSelectElement.idl +++ b/dom/interfaces/html/nsIDOMHTMLSelectElement.idl @@ -53,7 +53,7 @@ interface nsIDOMValidityState; -[scriptable, uuid(58cd01b8-c3f2-4e58-b39d-8a0ba941717e)] +[scriptable, uuid(5aeb2480-cb21-4483-b9b3-0c914502eb81)] interface nsIDOMHTMLSelectElement : nsIDOMHTMLElement { attribute boolean autofocus; @@ -70,7 +70,7 @@ interface nsIDOMHTMLSelectElement : nsIDOMHTMLElement nsIDOMNode item(in unsigned long index); nsIDOMNode namedItem(in DOMString name); void add(in nsIDOMHTMLElement element, - in nsIDOMHTMLElement before) + [optional] in nsIDOMHTMLElement before) raises(DOMException); void remove(in long index); From e704626a80456e5863062d887a8efa031840bdeb Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Wed, 22 Jun 2011 16:34:27 +0900 Subject: [PATCH 16/19] Bug 655655 - decom nsIPosixLocale. r=smontagu --HG-- rename : intl/locale/public/nsIPosixLocale.h => intl/locale/public/nsPosixLocale.h --- intl/build/nsI18nModule.cpp | 3 - intl/locale/public/Makefile.in | 2 +- intl/locale/public/nsIPosixLocale.h | 69 ----------------- intl/locale/public/nsLocaleCID.h | 21 ----- .../{src/unix => public}/nsPosixLocale.h | 29 +++---- intl/locale/src/nsLocaleConstructors.h | 2 - intl/locale/src/nsLocaleService.cpp | 76 +++++++++---------- intl/locale/src/unix/nsCollationUnix.cpp | 8 +- intl/locale/src/unix/nsDateTimeFormatUnix.cpp | 8 +- intl/locale/src/unix/nsPosixLocale.cpp | 23 ++---- intl/locale/src/unix/nsUNIXCharset.cpp | 1 - 11 files changed, 55 insertions(+), 187 deletions(-) delete mode 100644 intl/locale/public/nsIPosixLocale.h rename intl/locale/{src/unix => public}/nsPosixLocale.h (78%) diff --git a/intl/build/nsI18nModule.cpp b/intl/build/nsI18nModule.cpp index fc88eff2d8c..40491caeab8 100644 --- a/intl/build/nsI18nModule.cpp +++ b/intl/build/nsI18nModule.cpp @@ -96,7 +96,6 @@ NS_DEFINE_NAMED_CID(NS_COLLATION_CID); NS_DEFINE_NAMED_CID(NS_DATETIMEFORMAT_CID); #endif #ifdef USE_UNIX_LOCALE -NS_DEFINE_NAMED_CID(NS_POSIXLOCALE_CID); NS_DEFINE_NAMED_CID(NS_COLLATION_CID); NS_DEFINE_NAMED_CID(NS_DATETIMEFORMAT_CID); #endif @@ -132,7 +131,6 @@ static const mozilla::Module::CIDEntry kIntlCIDs[] = { { &kNS_DATETIMEFORMAT_CID, false, NULL, nsDateTimeFormatWinConstructor }, #endif #ifdef USE_UNIX_LOCALE - { &kNS_POSIXLOCALE_CID, false, NULL, nsPosixLocaleConstructor }, { &kNS_COLLATION_CID, false, NULL, nsCollationUnixConstructor }, { &kNS_DATETIMEFORMAT_CID, false, NULL, nsDateTimeFormatUnixConstructor }, #endif @@ -170,7 +168,6 @@ static const mozilla::Module::ContractIDEntry kIntlContracts[] = { { NS_DATETIMEFORMAT_CONTRACTID, &kNS_DATETIMEFORMAT_CID }, #endif #ifdef USE_UNIX_LOCALE - { NS_POSIXLOCALE_CONTRACTID, &kNS_POSIXLOCALE_CID }, { NS_COLLATION_CONTRACTID, &kNS_COLLATION_CID }, { NS_DATETIMEFORMAT_CONTRACTID, &kNS_DATETIMEFORMAT_CID }, #endif diff --git a/intl/locale/public/Makefile.in b/intl/locale/public/Makefile.in index b4a7947beaa..aafb09d2d7a 100644 --- a/intl/locale/public/Makefile.in +++ b/intl/locale/public/Makefile.in @@ -49,7 +49,7 @@ EXPORTS = \ nsDateTimeFormatCID.h \ nsIDateTimeFormat.h \ nsILanguageAtomService.h \ - nsIPosixLocale.h \ + nsPosixLocale.h \ nsIOS2Locale.h \ nsWin32Locale.h \ nsICharsetAlias.h \ diff --git a/intl/locale/public/nsIPosixLocale.h b/intl/locale/public/nsIPosixLocale.h deleted file mode 100644 index 2cbe9e8a9aa..00000000000 --- a/intl/locale/public/nsIPosixLocale.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Henry Sobotka - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef nsIPosixLocale_h__ -#define nsIPosixLocale_h__ - - -#include "nsISupports.h" -#include "nscore.h" -#include "nsString.h" - -/* a434957c-6514-447c-991b-2117b633359c */ -#define NS_IPOSIXLOCALE_IID \ -{ 0xa434957c, \ - 0x6514, \ - 0x447c, \ - {0x99, 0x1b, 0x21, 0x17, 0xb6, 0x33, 0x35, 0x9c} } - -#define MAX_LANGUAGE_CODE_LEN 3 -#define MAX_COUNTRY_CODE_LEN 3 -#define MAX_LOCALE_LEN 128 -#define MAX_EXTRA_LEN 65 - -class nsIPosixLocale : public nsISupports { - -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPOSIXLOCALE_IID) - - NS_IMETHOD GetPlatformLocale(const nsAString& locale, nsACString& posixLocale) = 0; - NS_IMETHOD GetXPLocale(const char* posixLocale, nsAString& locale) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIPosixLocale, NS_IPOSIXLOCALE_IID) - -#endif diff --git a/intl/locale/public/nsLocaleCID.h b/intl/locale/public/nsLocaleCID.h index b21db93a97b..de547c5307b 100644 --- a/intl/locale/public/nsLocaleCID.h +++ b/intl/locale/public/nsLocaleCID.h @@ -37,27 +37,6 @@ #ifndef nsLocaleCID_h__ #define nsLocaleCID_h__ -// {D92D57C3-BA1D-11d2-AF0C-0060089FE59B} -#define NS_WIN32LOCALE_CID \ -{ 0xd92d57c3, 0xba1d, 0x11d2, \ -{ 0xaf, 0xc, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } } - -#define NS_WIN32LOCALE_CONTRACTID "@mozilla.org/locale/win32-locale;1" - -// {D92D57C4-BA1D-11d2-AF0C-0060089FE59B} -#define NS_MACLOCALE_CID \ -{ 0xd92d57c4, 0xba1d, 0x11d2, \ -{ 0xaf, 0xc, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } } - -#define NS_MACLOCALE_CONTRACTID "@mozilla.org/locale/mac-locale;1" - -// {D92D57C5-BA1D-11d2-AF0C-0060089FE59B} -#define NS_POSIXLOCALE_CID \ -{ 0xd92d57c5, 0xba1d, 0x11d2, \ -{ 0xaf, 0xc, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } } - -#define NS_POSIXLOCALE_CONTRACTID "@mozilla.org/locale/posix-locale;1" - // {F25F74F1-FB59-11d3-A9F2-00203522A03C} #define NS_OS2LOCALE_CID \ { 0xf25f74f1, 0xfb59, 0x11d3, \ diff --git a/intl/locale/src/unix/nsPosixLocale.h b/intl/locale/public/nsPosixLocale.h similarity index 78% rename from intl/locale/src/unix/nsPosixLocale.h rename to intl/locale/public/nsPosixLocale.h index 7fa25095189..3e6f7f56a7c 100644 --- a/intl/locale/src/unix/nsPosixLocale.h +++ b/intl/locale/public/nsPosixLocale.h @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Henry Sobotka * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -34,33 +35,23 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ -#ifndef nsPosixLocale_h__ -#define nsPosixLocale_h__ +#ifndef nsIPosixLocale_h__ +#define nsIPosixLocale_h__ -#include "nsISupports.h" #include "nscore.h" #include "nsString.h" -#include "nsIPosixLocale.h" +#define MAX_LANGUAGE_CODE_LEN 3 +#define MAX_COUNTRY_CODE_LEN 3 +#define MAX_LOCALE_LEN 128 +#define MAX_EXTRA_LEN 65 - -class nsPosixLocale : public nsIPosixLocale { - - NS_DECL_ISUPPORTS +class nsPosixLocale { public: - - nsPosixLocale(); - virtual ~nsPosixLocale(); - - NS_IMETHOD GetPlatformLocale(const nsAString& locale, nsACString& posixLocale); - NS_IMETHOD GetXPLocale(const char* posixLocale, nsAString& locale); - -protected: - inline PRBool ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator); - + static nsresult GetPlatformLocale(const nsAString& locale, nsACString& posixLocale); + static nsresult GetXPLocale(const char* posixLocale, nsAString& locale); }; - #endif diff --git a/intl/locale/src/nsLocaleConstructors.h b/intl/locale/src/nsLocaleConstructors.h index 5966eee9d3b..448c018860a 100644 --- a/intl/locale/src/nsLocaleConstructors.h +++ b/intl/locale/src/nsLocaleConstructors.h @@ -77,7 +77,6 @@ #ifdef USE_UNIX_LOCALE #include "nsCollationUnix.h" #include "nsDateTimeFormatUnix.h" -#include "nsPosixLocale.h" #endif #define NSLOCALE_MAKE_CTOR(ctor_, iface_, func_) \ @@ -110,7 +109,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDateTimeFormatWin) #endif #ifdef USE_UNIX_LOCALE -NS_GENERIC_FACTORY_CONSTRUCTOR(nsPosixLocale) NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationUnix) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDateTimeFormatUnix) #endif diff --git a/intl/locale/src/nsLocaleService.cpp b/intl/locale/src/nsLocaleService.cpp index ead92154310..b2a794bc251 100644 --- a/intl/locale/src/nsLocaleService.cpp +++ b/intl/locale/src/nsLocaleService.cpp @@ -64,7 +64,7 @@ #elif defined(XP_UNIX) # include # include -# include "nsIPosixLocale.h" +# include "nsPosixLocale.h" #endif // @@ -157,55 +157,47 @@ nsLocaleService::nsLocaleService(void) NS_ENSURE_SUCCESS(rv, ); #endif #if defined(XP_UNIX) && !defined(XP_MACOSX) - nsCOMPtr posixConverter = do_GetService(NS_POSIXLOCALE_CONTRACTID); - - nsAutoString xpLocale, platformLocale; - if (posixConverter) { - nsAutoString category, category_platform; - int i; - - nsRefPtr resultLocale(new nsLocale()); - if ( resultLocale == NULL ) { - return; - } - + nsRefPtr resultLocale(new nsLocale()); + NS_ENSURE_TRUE(resultLocale, ); #ifdef MOZ_WIDGET_QT - const char* lang = QLocale::system().name().toAscii(); + const char* lang = QLocale::system().name().toAscii(); #else - // Get system configuration - const char* lang = getenv("LANG"); + // Get system configuration + const char* lang = getenv("LANG"); #endif - for( i = 0; i < LocaleListLength; i++ ) { - nsresult result; - // setlocale( , "") evaluates LC_* and LANG - char* lc_temp = setlocale(posix_locale_category[i], ""); - CopyASCIItoUTF16(LocaleList[i], category); - category_platform = category; - category_platform.AppendLiteral("##PLATFORM"); - if (lc_temp != nsnull) { - result = posixConverter->GetXPLocale(lc_temp, xpLocale); - CopyASCIItoUTF16(lc_temp, platformLocale); + nsAutoString xpLocale, platformLocale; + nsAutoString category, category_platform; + int i; + + for( i = 0; i < LocaleListLength; i++ ) { + nsresult result; + // setlocale( , "") evaluates LC_* and LANG + char* lc_temp = setlocale(posix_locale_category[i], ""); + CopyASCIItoUTF16(LocaleList[i], category); + category_platform = category; + category_platform.AppendLiteral("##PLATFORM"); + if (lc_temp != nsnull) { + result = nsPosixLocale::GetXPLocale(lc_temp, xpLocale); + CopyASCIItoUTF16(lc_temp, platformLocale); + } else { + if ( lang == nsnull ) { + platformLocale.AssignLiteral("en_US"); + result = nsPosixLocale::GetXPLocale("en-US", xpLocale); } else { - if ( lang == nsnull ) { - platformLocale.AssignLiteral("en_US"); - result = posixConverter->GetXPLocale("en-US", xpLocale); - } - else { - CopyASCIItoUTF16(lang, platformLocale); - result = posixConverter->GetXPLocale(lang, xpLocale); - } + CopyASCIItoUTF16(lang, platformLocale); + result = nsPosixLocale::GetXPLocale(lang, xpLocale); } - if (NS_FAILED(result)) { - return; - } - resultLocale->AddCategory(category, xpLocale); - resultLocale->AddCategory(category_platform, platformLocale); } - mSystemLocale = do_QueryInterface(resultLocale); - mApplicationLocale = do_QueryInterface(resultLocale); - } // if ( NS_SUCCEEDED )... + if (NS_FAILED(result)) { + return; + } + resultLocale->AddCategory(category, xpLocale); + resultLocale->AddCategory(category_platform, platformLocale); + } + mSystemLocale = do_QueryInterface(resultLocale); + mApplicationLocale = do_QueryInterface(resultLocale); #endif // XP_UNIX #ifdef XP_OS2 diff --git a/intl/locale/src/unix/nsCollationUnix.cpp b/intl/locale/src/unix/nsCollationUnix.cpp index ed5e4a6a73a..7940db89e71 100644 --- a/intl/locale/src/unix/nsCollationUnix.cpp +++ b/intl/locale/src/unix/nsCollationUnix.cpp @@ -41,10 +41,9 @@ #include "nsCollationUnix.h" #include "nsIServiceManager.h" #include "nsIComponentManager.h" -#include "nsLocaleCID.h" #include "nsILocaleService.h" #include "nsIPlatformCharset.h" -#include "nsIPosixLocale.h" +#include "nsPosixLocale.h" #include "nsCOMPtr.h" #include "nsIPrefBranch.h" #include "nsIPrefService.h" @@ -126,10 +125,7 @@ nsresult nsCollationUnix::Initialize(nsILocale* locale) localeStr.AssignLiteral("C"); } - nsCOMPtr posixLocale = do_GetService(NS_POSIXLOCALE_CONTRACTID, &res); - if (NS_SUCCEEDED(res)) { - res = posixLocale->GetPlatformLocale(localeStr, mLocale); - } + nsPosixLocale::GetPlatformLocale(localeStr, mLocale); nsCOMPtr platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &res); if (NS_SUCCEEDED(res)) { diff --git a/intl/locale/src/unix/nsDateTimeFormatUnix.cpp b/intl/locale/src/unix/nsDateTimeFormatUnix.cpp index 02db84ed4e7..35b733face2 100644 --- a/intl/locale/src/unix/nsDateTimeFormatUnix.cpp +++ b/intl/locale/src/unix/nsDateTimeFormatUnix.cpp @@ -41,10 +41,9 @@ #include "nsIServiceManager.h" #include "nsDateTimeFormatUnix.h" #include "nsIComponentManager.h" -#include "nsLocaleCID.h" #include "nsILocaleService.h" #include "nsIPlatformCharset.h" -#include "nsIPosixLocale.h" +#include "nsPosixLocale.h" #include "nsCRT.h" #include "nsReadableUtils.h" #include "nsUnicharUtils.h" @@ -103,10 +102,7 @@ nsresult nsDateTimeFormatUnix::Initialize(nsILocale* locale) if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) { mLocale = localeStr; // cache locale name - nsCOMPtr posixLocale = do_GetService(NS_POSIXLOCALE_CONTRACTID, &res); - if (NS_SUCCEEDED(res)) { - res = posixLocale->GetPlatformLocale(mLocale, mPlatformLocale); - } + nsPosixLocale::GetPlatformLocale(mLocale, mPlatformLocale); nsCOMPtr platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &res); if (NS_SUCCEEDED(res)) { diff --git a/intl/locale/src/unix/nsPosixLocale.cpp b/intl/locale/src/unix/nsPosixLocale.cpp index 04835ec30c3..b9ad905a04b 100644 --- a/intl/locale/src/unix/nsPosixLocale.cpp +++ b/intl/locale/src/unix/nsPosixLocale.cpp @@ -35,28 +35,17 @@ * * ***** END LICENSE BLOCK ***** */ -#include "nsISupports.h" #include "nscore.h" #include "nsString.h" #include "nsPosixLocale.h" -#include "nsLocaleCID.h" #include "prprf.h" #include "plstr.h" #include "nsReadableUtils.h" -/* nsPosixLocale ISupports */ -NS_IMPL_ISUPPORTS1(nsPosixLocale, nsIPosixLocale) +static PRBool +ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator); -nsPosixLocale::nsPosixLocale(void) -{ -} - -nsPosixLocale::~nsPosixLocale(void) -{ - -} - -NS_IMETHODIMP +nsresult nsPosixLocale::GetPlatformLocale(const nsAString& locale, nsACString& posixLocale) { char country_code[MAX_COUNTRY_CODE_LEN+1]; @@ -96,7 +85,7 @@ nsPosixLocale::GetPlatformLocale(const nsAString& locale, nsACString& posixLocal return NS_ERROR_FAILURE; } -NS_IMETHODIMP +nsresult nsPosixLocale::GetXPLocale(const char* posixLocale, nsAString& locale) { char country_code[MAX_COUNTRY_CODE_LEN+1]; @@ -140,8 +129,8 @@ nsPosixLocale::GetXPLocale(const char* posixLocale, nsAString& locale) // // returns PR_FALSE/PR_TRUE depending on if it was of the form LL-CC.Extra -PRBool -nsPosixLocale::ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator) +static PRBool +ParseLocaleString(const char* locale_string, char* language, char* country, char* extra, char separator) { const char *src = locale_string; char modifier[MAX_EXTRA_LEN+1]; diff --git a/intl/locale/src/unix/nsUNIXCharset.cpp b/intl/locale/src/unix/nsUNIXCharset.cpp index a3c9516fac3..2c04a494aca 100644 --- a/intl/locale/src/unix/nsUNIXCharset.cpp +++ b/intl/locale/src/unix/nsUNIXCharset.cpp @@ -41,7 +41,6 @@ #include "nsUConvPropertySearch.h" #include "nsCOMPtr.h" #include "nsReadableUtils.h" -#include "nsLocaleCID.h" #include "nsIComponentManager.h" #include "nsIServiceManager.h" #include "nsIUnicodeDecoder.h" From e62f2bb247b4014d26c91b9651ffaf577c1ecd32 Mon Sep 17 00:00:00 2001 From: "bjarne@runitsoft.com" Date: Wed, 22 Jun 2011 10:49:35 +0200 Subject: [PATCH 17/19] Bug 654926 - Hang in nsDiskCacheStreamIO::CloseOutputStream while downloading WebM video from YouTube r=michal.novotny, bjarne --- netwerk/cache/nsCacheEntryDescriptor.cpp | 34 +++-- netwerk/cache/nsCacheEntryDescriptor.h | 21 +-- netwerk/cache/nsDiskCacheStreams.cpp | 7 +- netwerk/test/unit/test_bug654926.js | 131 ++++++++++++++++++ .../test/unit/test_bug654926_doom_and_read.js | 100 +++++++++++++ netwerk/test/unit/test_bug654926_test_seek.js | 87 ++++++++++++ netwerk/test/unit/xpcshell.ini | 3 + 7 files changed, 362 insertions(+), 21 deletions(-) create mode 100644 netwerk/test/unit/test_bug654926.js create mode 100644 netwerk/test/unit/test_bug654926_doom_and_read.js create mode 100644 netwerk/test/unit/test_bug654926_test_seek.js diff --git a/netwerk/cache/nsCacheEntryDescriptor.cpp b/netwerk/cache/nsCacheEntryDescriptor.cpp index 0b2ed96c7eb..a8c2196255e 100644 --- a/netwerk/cache/nsCacheEntryDescriptor.cpp +++ b/netwerk/cache/nsCacheEntryDescriptor.cpp @@ -609,22 +609,34 @@ nsOutputStreamWrapper::LazyInit() nsCacheEntry* cacheEntry = mDescriptor->CacheEntry(); if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE; - rv = nsCacheService::OpenOutputStreamForEntry(cacheEntry, mode, mStartOffset, - getter_AddRefs(mOutput)); - if (NS_FAILED(rv)) return rv; + NS_ASSERTION(mOutput == nsnull, "mOutput set in LazyInit"); - mDescriptor->mOutput = mOutput; + nsCOMPtr stream; + rv = nsCacheService::OpenOutputStreamForEntry(cacheEntry, mode, mStartOffset, + getter_AddRefs(stream)); + if (NS_FAILED(rv)) + return rv; nsCacheDevice* device = cacheEntry->CacheDevice(); - if (!device) return NS_ERROR_NOT_AVAILABLE; + if (device) { + // the entry has been truncated to mStartOffset bytes, inform device + PRInt32 size = cacheEntry->DataSize(); + rv = device->OnDataSizeChange(cacheEntry, mStartOffset - size); + if (NS_SUCCEEDED(rv)) + cacheEntry->SetDataSize(mStartOffset); + } else { + rv = NS_ERROR_NOT_AVAILABLE; + } - // the entry has been truncated to mStartOffset bytes, inform the device. - PRInt32 size = cacheEntry->DataSize(); - rv = device->OnDataSizeChange(cacheEntry, mStartOffset - size); - if (NS_FAILED(rv)) return rv; - - cacheEntry->SetDataSize(mStartOffset); + // If anything above failed, clean up internal state and get out of here + // (see bug #654926)... + if (NS_FAILED(rv)) { + mDescriptor->InternalCleanup(stream); + return rv; + } + // ... otherwise, set members and mark initialized + mDescriptor->mOutput = mOutput = stream; mInitialized = PR_TRUE; return NS_OK; } diff --git a/netwerk/cache/nsCacheEntryDescriptor.h b/netwerk/cache/nsCacheEntryDescriptor.h index c74ed534574..4416c5b9c9c 100644 --- a/netwerk/cache/nsCacheEntryDescriptor.h +++ b/netwerk/cache/nsCacheEntryDescriptor.h @@ -77,18 +77,21 @@ public: void CloseOutput(void) { - if (mOutput) { - nsCOMPtr tmp (do_QueryInterface(mOutput)); - if (tmp) - tmp->CloseInternal(); - else - mOutput->Close(); - - mOutput = nsnull; - } + InternalCleanup(mOutput); + mOutput = nsnull; } private: + void InternalCleanup(nsIOutputStream *stream) + { + if (stream) { + nsCOMPtr tmp (do_QueryInterface(stream)); + if (tmp) + tmp->CloseInternal(); + else + stream->Close(); + } + } /************************************************************************* diff --git a/netwerk/cache/nsDiskCacheStreams.cpp b/netwerk/cache/nsDiskCacheStreams.cpp index ef1b24fea2a..7786818c56f 100644 --- a/netwerk/cache/nsDiskCacheStreams.cpp +++ b/netwerk/cache/nsDiskCacheStreams.cpp @@ -484,8 +484,13 @@ nsDiskCacheStreamIO::Flush() CACHE_LOG_DEBUG(("CACHE: Flush [%x doomed=%u]\n", mBinding->mRecord.HashNumber(), mBinding->mDoomed)); - if (!mBufDirty) + if (!mBufDirty) { + if (mFD) { + (void) PR_Close(mFD); + mFD = nsnull; + } return NS_OK; + } // write data to cache blocks, or flush mBuffer to file nsDiskCacheMap *cacheMap = mDevice->CacheMap(); // get map reference diff --git a/netwerk/test/unit/test_bug654926.js b/netwerk/test/unit/test_bug654926.js new file mode 100644 index 00000000000..f840e90a226 --- /dev/null +++ b/netwerk/test/unit/test_bug654926.js @@ -0,0 +1,131 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +var _CSvc; +function get_cache_service() { + if (_CSvc) + return _CSvc; + + return _CSvc = Cc["@mozilla.org/network/cache-service;1"]. + getService(Ci.nsICacheService); +} + +function get_ostream_for_entry(key, asFile, append, entryRef) +{ + var cache = get_cache_service(); + var session = cache.createSession( + "HTTP", + asFile ? Ci.nsICache.STORE_ON_DISK_AS_FILE + : Ci.nsICache.STORE_ON_DISK, + Ci.nsICache.STREAM_BASED); + var cacheEntry = session.openCacheEntry( + key, + append ? Ci.nsICache.ACCESS_READ_WRITE + : Ci.nsICache.ACCESS_WRITE, + true); + var oStream = cacheEntry.openOutputStream(append ? cacheEntry.dataSize : 0); + entryRef.value = cacheEntry; + return oStream; +} + +function sync_with_cache_IO_thread(aFunc) +{ + do_check_eq(sync_with_cache_IO_thread_cb.listener, null); + sync_with_cache_IO_thread_cb.listener = aFunc; + var cache = get_cache_service(); + var session = cache.createSession( + "HTTP", + Ci.nsICache.STORE_ON_DISK, + Ci.nsICache.STREAM_BASED); + var cacheEntry = session.asyncOpenCacheEntry( + "nonexistententry", + Ci.nsICache.ACCESS_READ, + sync_with_cache_IO_thread_cb); +} +var sync_with_cache_IO_thread_cb = { + listener: null, + + onCacheEntryAvailable: function oCEA(descriptor, accessGranted, status) { + do_check_eq(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND); + cb = this.listener; + this.listener = null; + do_timeout(0, cb); + } +}; + +function gen_1MiB() +{ + var i; + var data="x"; + for (i=0 ; i < 20 ; i++) + data+=data; + return data; +} + +function write_and_check(str, data, len) +{ + var written = str.write(data, len); + if (written != len) { + do_throw("str.write has not written all data!\n" + + " Expected: " + len + "\n" + + " Actual: " + written + "\n"); + } +} + +function write_datafile() +{ + var entry = {}; + var oStr = get_ostream_for_entry("data", true, false, entry); + var data = gen_1MiB(); + + // 6MiB + var i; + for (i=0 ; i<6 ; i++) + write_and_check(oStr, data, data.length); + + oStr.close(); + entry.value.close(); + + // wait until writing is done, then append to entry + sync_with_cache_IO_thread(append_datafile); +} + +function append_datafile() +{ + var entry = {}; + var oStr = get_ostream_for_entry("data", false, true, entry); + var data = gen_1MiB(); + + + // append 1MiB + try { + write_and_check(oStr, data, data.length); + do_throw(); + } + catch (ex) { } + + // closing the ostream should fail in this case + try { + oStr.close(); + do_throw(); + } + catch (ex) { } + + entry.value.close(); + + // wait until cache-operations have finished, then finish test + sync_with_cache_IO_thread(do_test_finished); +} + +function run_test() { + do_get_profile(); + + // clear the cache + get_cache_service().evictEntries(Ci.nsICache.STORE_ANYWHERE); + + // wait until clearing is done, then force to write file bigger than 5MiB + sync_with_cache_IO_thread(write_datafile); + + do_test_pending(); +} diff --git a/netwerk/test/unit/test_bug654926_doom_and_read.js b/netwerk/test/unit/test_bug654926_doom_and_read.js new file mode 100644 index 00000000000..c180972f83b --- /dev/null +++ b/netwerk/test/unit/test_bug654926_doom_and_read.js @@ -0,0 +1,100 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +var _CSvc; +function get_cache_service() { + if (_CSvc) + return _CSvc; + + return _CSvc = Cc["@mozilla.org/network/cache-service;1"]. + getService(Ci.nsICacheService); +} + +function get_ostream_for_entry(key, asFile, append, entryRef) +{ + var cache = get_cache_service(); + var session = cache.createSession( + "HTTP", + asFile ? Ci.nsICache.STORE_ON_DISK_AS_FILE + : Ci.nsICache.STORE_ON_DISK, + Ci.nsICache.STREAM_BASED); + var cacheEntry = session.openCacheEntry( + key, + append ? Ci.nsICache.ACCESS_READ_WRITE + : Ci.nsICache.ACCESS_WRITE, + true); + var oStream = cacheEntry.openOutputStream(append ? cacheEntry.dataSize : 0); + entryRef.value = cacheEntry; + return oStream; +} + +function gen_1MiB() +{ + var i; + var data="x"; + for (i=0 ; i < 20 ; i++) + data+=data; + return data; +} + +function write_and_check(str, data, len) +{ + var written = str.write(data, len); + if (written != len) { + do_throw("str.write has not written all data!\n" + + " Expected: " + len + "\n" + + " Actual: " + written + "\n"); + } +} + +function make_input_stream_scriptable(input) { + var wrapper = Cc["@mozilla.org/scriptableinputstream;1"]. + createInstance(Ci.nsIScriptableInputStream); + wrapper.init(input); + return wrapper; +} + +function write_datafile() +{ + var entry = {}; + var oStr = get_ostream_for_entry("data", true, false, entry); + var data = gen_1MiB(); + + write_and_check(oStr, data, data.length); + + oStr.close(); + entry.value.close(); +} + +function test_read_after_doom() +{ + var entry = {}; + var oStr = get_ostream_for_entry("data", false, true, entry); + var data = gen_1MiB(); + + entry.value.doom(); + write_and_check(oStr, data, data.length); + + oStr.close(); + + var iStr = make_input_stream_scriptable(entry.value.openInputStream(0)); + var read = iStr.read(iStr.available()); + do_check_eq(read.length, 2*1024*1024); + iStr.close(); + + entry.value.close(); +} + +function run_test() { + do_get_profile(); + + // clear the cache + get_cache_service().evictEntries(Ci.nsICache.STORE_ANYWHERE); + + // force to write file bigger than 5MiB + write_datafile(); + + // open, doom, append, read + test_read_after_doom(); +} diff --git a/netwerk/test/unit/test_bug654926_test_seek.js b/netwerk/test/unit/test_bug654926_test_seek.js new file mode 100644 index 00000000000..61b70b99bb1 --- /dev/null +++ b/netwerk/test/unit/test_bug654926_test_seek.js @@ -0,0 +1,87 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +var _CSvc; +function get_cache_service() { + if (_CSvc) + return _CSvc; + + return _CSvc = Cc["@mozilla.org/network/cache-service;1"]. + getService(Ci.nsICacheService); +} + +function get_ostream_for_entry(key, asFile, append, entryRef) +{ + var cache = get_cache_service(); + var session = cache.createSession( + "HTTP", + asFile ? Ci.nsICache.STORE_ON_DISK_AS_FILE + : Ci.nsICache.STORE_ON_DISK, + Ci.nsICache.STREAM_BASED); + var cacheEntry = session.openCacheEntry( + key, + append ? Ci.nsICache.ACCESS_READ_WRITE + : Ci.nsICache.ACCESS_WRITE, + true); + var oStream = cacheEntry.openOutputStream(append ? cacheEntry.dataSize : 0); + entryRef.value = cacheEntry; + return oStream; +} + +function gen_1MiB() +{ + var i; + var data="x"; + for (i=0 ; i < 20 ; i++) + data+=data; + return data; +} + +function write_and_check(str, data, len) +{ + var written = str.write(data, len); + if (written != len) { + do_throw("str.write has not written all data!\n" + + " Expected: " + len + "\n" + + " Actual: " + written + "\n"); + } +} + +function write_datafile() +{ + var entry = {}; + var oStr = get_ostream_for_entry("data", true, false, entry); + var data = gen_1MiB(); + + write_and_check(oStr, data, data.length); + + oStr.close(); + entry.value.close(); +} + +function open_for_readwrite() +{ + var entry = {}; + var oStr = get_ostream_for_entry("data", false, true, entry); + + // Opening the entry for appending data calls nsDiskCacheStreamIO::Seek() + // which initializes mFD. If no data is written then mBufDirty is false and + // mFD won't be closed in nsDiskCacheStreamIO::Flush(). + + oStr.close(); + entry.value.close(); +} + +function run_test() { + do_get_profile(); + + // clear the cache + get_cache_service().evictEntries(Ci.nsICache.STORE_ANYWHERE); + + // force to write file bigger than 5MiB + write_datafile(); + + // try to open the entry for appending + open_for_readwrite(); +} diff --git a/netwerk/test/unit/xpcshell.ini b/netwerk/test/unit/xpcshell.ini index 6dad429c55f..ad8ef1eb50f 100644 --- a/netwerk/test/unit/xpcshell.ini +++ b/netwerk/test/unit/xpcshell.ini @@ -60,6 +60,9 @@ tail = [test_bug633743.js] [test_bug652761.js] [test_bug651100.js] +[test_bug654926.js] +[test_bug654926_doom_and_read.js] +[test_bug654926_test_seek.js] [test_bug659569.js] [test_bug660066.js] [test_cacheflags.js] From aeadb6fd97db2c6586e9d3d37e809b68d2ad5866 Mon Sep 17 00:00:00 2001 From: Kai Liu Date: Wed, 22 Jun 2011 12:32:50 +0200 Subject: [PATCH 18/19] Bug 661846: Move the Windows classic/XP native menu padding calculation from GetWidgetBorder to GetWidgetPadding. r=jmathies --- widget/src/windows/nsNativeThemeWin.cpp | 30 ++++++++++++++++--------- widget/src/windows/nsNativeThemeWin.h | 5 +++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/widget/src/windows/nsNativeThemeWin.cpp b/widget/src/windows/nsNativeThemeWin.cpp index b0e09967ce6..e40b5c50971 100644 --- a/widget/src/windows/nsNativeThemeWin.cpp +++ b/widget/src/windows/nsNativeThemeWin.cpp @@ -1795,7 +1795,7 @@ nsNativeThemeWin::GetWidgetPadding(nsDeviceContext* aContext, } if (!theme) - return PR_FALSE; + return ClassicGetWidgetPadding(aContext, aFrame, aWidgetType, aResult); if (aWidgetType == NS_THEME_MENUPOPUP) { @@ -2468,18 +2468,30 @@ nsNativeThemeWin::ClassicGetWidgetBorder(nsDeviceContext* aContext, case NS_THEME_MENUPOPUP: (*aResult).top = (*aResult).left = (*aResult).bottom = (*aResult).right = 3; break; + default: + (*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0; + break; + } + return NS_OK; +} + +PRBool +nsNativeThemeWin::ClassicGetWidgetPadding(nsDeviceContext* aContext, + nsIFrame* aFrame, + PRUint8 aWidgetType, + nsIntMargin* aResult) +{ + switch (aWidgetType) { case NS_THEME_MENUITEM: case NS_THEME_CHECKMENUITEM: case NS_THEME_RADIOMENUITEM: { PRInt32 part, state; PRBool focused; - nsresult rv; - rv = ClassicGetThemePartAndState(aFrame, aWidgetType, part, state, focused); - if (NS_FAILED(rv)) - return rv; + if (NS_FAILED(ClassicGetThemePartAndState(aFrame, aWidgetType, part, state, focused))) + return PR_FALSE; - if (part == 1) { // top level menu + if (part == 1) { // top-level menu if (nsUXThemeData::sFlatMenus || !(state & DFCS_PUSHED)) { (*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 2; } @@ -2493,13 +2505,11 @@ nsNativeThemeWin::ClassicGetWidgetBorder(nsDeviceContext* aContext, (*aResult).top = 0; (*aResult).bottom = (*aResult).left = (*aResult).right = 2; } - break; + return PR_TRUE; } default: - (*aResult).top = (*aResult).bottom = (*aResult).left = (*aResult).right = 0; - break; + return PR_FALSE; } - return NS_OK; } nsresult diff --git a/widget/src/windows/nsNativeThemeWin.h b/widget/src/windows/nsNativeThemeWin.h index 2c26cb4bc04..b689cb572a4 100644 --- a/widget/src/windows/nsNativeThemeWin.h +++ b/widget/src/windows/nsNativeThemeWin.h @@ -114,6 +114,11 @@ protected: PRUint8 aWidgetType, nsIntMargin* aResult); + PRBool ClassicGetWidgetPadding(nsDeviceContext* aContext, + nsIFrame* aFrame, + PRUint8 aWidgetType, + nsIntMargin* aResult); + nsresult ClassicGetMinimumWidgetSize(nsRenderingContext* aContext, nsIFrame* aFrame, PRUint8 aWidgetType, nsIntSize* aResult, From c1af47f4bc94c5282492c6c5ab736bb03e10b87e Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Wed, 22 Jun 2011 12:41:00 +0200 Subject: [PATCH 19/19] Bug 665612 - More cleanup around mInputData and IsSingleLineTextControl(). f=ehsan r=bz --- .../html/content/src/nsHTMLInputElement.cpp | 148 ++++++++++-------- 1 file changed, 80 insertions(+), 68 deletions(-) diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 4197e8070fe..1fd18fa9663 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -998,37 +998,42 @@ nsHTMLInputElement::GetValue(nsAString& aValue) nsresult nsHTMLInputElement::GetValueInternal(nsAString& aValue) const { - nsTextEditorState* state = GetEditorState(); - if (state) { - state->GetValue(aValue, PR_TRUE); - return NS_OK; - } - - if (mType == NS_FORM_INPUT_FILE) { - if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) { - if (mFiles.Count()) { - return mFiles[0]->GetMozFullPath(aValue); - } - else { - aValue.Truncate(); - } - } else { - // Just return the leaf name - if (mFiles.Count() == 0 || NS_FAILED(mFiles[0]->GetName(aValue))) { - aValue.Truncate(); - } - } - - return NS_OK; - } - - // Treat value == defaultValue for other input elements - if (!GetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue) && - (mType == NS_FORM_INPUT_RADIO || mType == NS_FORM_INPUT_CHECKBOX)) { - // The default value of a radio or checkbox input is "on". - aValue.AssignLiteral("on"); + switch (GetValueMode()) { + case VALUE_MODE_VALUE: + mInputData.mState->GetValue(aValue, PR_TRUE); + return NS_OK; + + case VALUE_MODE_FILENAME: + if (nsContentUtils::IsCallerTrustedForCapability("UniversalFileRead")) { + if (mFiles.Count()) { + return mFiles[0]->GetMozFullPath(aValue); + } + else { + aValue.Truncate(); + } + } else { + // Just return the leaf name + if (mFiles.Count() == 0 || NS_FAILED(mFiles[0]->GetName(aValue))) { + aValue.Truncate(); + } + } + + return NS_OK; + + case VALUE_MODE_DEFAULT: + // Treat defaultValue as value. + GetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue); + return NS_OK; + + case VALUE_MODE_DEFAULT_ON: + // Treat default value as value and returns "on" if no value. + if (!GetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue)) { + aValue.AssignLiteral("on"); + } + return NS_OK; } + // This return statement is required for some compilers. return NS_OK; } @@ -1393,48 +1398,61 @@ nsHTMLInputElement::SetValueInternal(const nsAString& aValue, PRBool aUserInput, PRBool aSetValueChanged) { - NS_PRECONDITION(mType != NS_FORM_INPUT_FILE, + NS_PRECONDITION(GetValueMode() != VALUE_MODE_FILENAME, "Don't call SetValueInternal for file inputs"); - if (mType == NS_FORM_INPUT_FILE) { - return NS_ERROR_UNEXPECTED; - } + switch (GetValueMode()) { + case VALUE_MODE_VALUE: + { + // At the moment, only single line text control have to sanitize their value + // Because we have to create a new string for that, we should prevent doing + // it if it's useless. + nsAutoString value(aValue); - if (IsSingleLineTextControl(PR_FALSE)) { - // At the moment, only single line text control have to sanitize their value - // Because we have to create a new string for that, we should prevent doing - // it if it's useless. - nsAutoString value(aValue); - if (!GET_BOOLBIT(mBitField, BF_PARSER_CREATING)) { - SanitizeValue(value); + if (!GET_BOOLBIT(mBitField, BF_PARSER_CREATING)) { + SanitizeValue(value); + } + + if (aSetValueChanged) { + SetValueChanged(PR_TRUE); + } + + mInputData.mState->SetValue(value, aUserInput); + + // This call might be useless in some situations because if the element is + // a single line text control, nsTextEditorState::SetValue will call + // nsHTMLInputElement::OnValueChanged which is going to call UpdateState() + // if the element is focused. This bug 665547. + if (PlaceholderApplies() && + HasAttr(kNameSpaceID_None, nsGkAtoms::placeholder)) { + UpdateState(true); + } + + return NS_OK; } - if (aSetValueChanged) { - SetValueChanged(PR_TRUE); - } - mInputData.mState->SetValue(value, aUserInput); + case VALUE_MODE_DEFAULT: + case VALUE_MODE_DEFAULT_ON: + // If the value of a hidden input was changed, we mark it changed so that we + // will know we need to save / restore the value. Yes, we are overloading + // the meaning of ValueChanged just a teensy bit to save a measly byte of + // storage space in nsHTMLInputElement. Yes, you are free to make a new flag, + // NEED_TO_SAVE_VALUE, at such time as mBitField becomes a 16-bit value. + if (mType == NS_FORM_INPUT_HIDDEN) { + SetValueChanged(PR_TRUE); + } - if (PlaceholderApplies() && - HasAttr(kNameSpaceID_None, nsGkAtoms::placeholder)) { - UpdateState(true); - } + // Treat value == defaultValue for other input elements. + return nsGenericHTMLFormElement::SetAttr(kNameSpaceID_None, + nsGkAtoms::value, aValue, + PR_TRUE); - return NS_OK; + case VALUE_MODE_FILENAME: + return NS_ERROR_UNEXPECTED; } - // If the value of a hidden input was changed, we mark it changed so that we - // will know we need to save / restore the value. Yes, we are overloading - // the meaning of ValueChanged just a teensy bit to save a measly byte of - // storage space in nsHTMLInputElement. Yes, you are free to make a new flag, - // NEED_TO_SAVE_VALUE, at such time as mBitField becomes a 16-bit value. - if (mType == NS_FORM_INPUT_HIDDEN) { - SetValueChanged(PR_TRUE); - } - - // Treat value == defaultValue for other input elements. - return nsGenericHTMLFormElement::SetAttr(kNameSpaceID_None, - nsGkAtoms::value, aValue, - PR_TRUE); + // This return statement is required for some compilers. + return NS_OK; } NS_IMETHODIMP @@ -1444,12 +1462,6 @@ nsHTMLInputElement::SetValueChanged(PRBool aValueChanged) SET_BOOLBIT(mBitField, BF_VALUE_CHANGED, aValueChanged); - if (!aValueChanged) { - if (!IsSingleLineTextControl(PR_FALSE)) { - FreeData(); - } - } - if (valueChangedBefore != aValueChanged) { UpdateState(true); }