diff --git a/modules/libpref/src/nsPrefBranch.cpp b/modules/libpref/src/nsPrefBranch.cpp index 423caff55dd..46bfcb0cd25 100644 --- a/modules/libpref/src/nsPrefBranch.cpp +++ b/modules/libpref/src/nsPrefBranch.cpp @@ -44,6 +44,7 @@ #endif #include "nsPrefBranch.h" +#include "nsPrefService.h" #include "nsILocalFile.h" #include "nsIObserverService.h" #include "nsXPCOM.h" @@ -52,6 +53,7 @@ #include "nsString.h" #include "nsReadableUtils.h" #include "nsXPIDLString.h" +#include "nsThreadUtils.h" #include "nsIStringBundle.h" #include "prefapi.h" #include "prmem.h" @@ -147,6 +149,10 @@ NS_INTERFACE_MAP_END NS_IMETHODIMP nsPrefBranch::GetRoot(char **aRoot) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG_POINTER(aRoot); mPrefRoot.Truncate(mPrefRootLength); *aRoot = ToNewCString(mPrefRoot); @@ -155,6 +161,10 @@ NS_IMETHODIMP nsPrefBranch::GetRoot(char **aRoot) NS_IMETHODIMP nsPrefBranch::GetPrefType(const char *aPrefName, PRInt32 *_retval) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG(aPrefName); const char *pref = getPrefName(aPrefName); *_retval = PREF_GetPrefType(pref); @@ -163,6 +173,10 @@ NS_IMETHODIMP nsPrefBranch::GetPrefType(const char *aPrefName, PRInt32 *_retval) NS_IMETHODIMP nsPrefBranch::GetBoolPref(const char *aPrefName, PRBool *_retval) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG(aPrefName); const char *pref = getPrefName(aPrefName); return PREF_GetBoolPref(pref, _retval, mIsDefault); @@ -170,6 +184,10 @@ NS_IMETHODIMP nsPrefBranch::GetBoolPref(const char *aPrefName, PRBool *_retval) NS_IMETHODIMP nsPrefBranch::SetBoolPref(const char *aPrefName, PRInt32 aValue) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot set pref from content process"); @@ -184,6 +202,10 @@ NS_IMETHODIMP nsPrefBranch::SetBoolPref(const char *aPrefName, PRInt32 aValue) NS_IMETHODIMP nsPrefBranch::GetCharPref(const char *aPrefName, char **_retval) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG(aPrefName); const char *pref = getPrefName(aPrefName); return PREF_CopyCharPref(pref, _retval, mIsDefault); @@ -191,6 +213,10 @@ NS_IMETHODIMP nsPrefBranch::GetCharPref(const char *aPrefName, char **_retval) NS_IMETHODIMP nsPrefBranch::SetCharPref(const char *aPrefName, const char *aValue) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot set pref from content process"); @@ -206,6 +232,10 @@ NS_IMETHODIMP nsPrefBranch::SetCharPref(const char *aPrefName, const char *aValu NS_IMETHODIMP nsPrefBranch::GetIntPref(const char *aPrefName, PRInt32 *_retval) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG(aPrefName); const char *pref = getPrefName(aPrefName); return PREF_GetIntPref(pref, _retval, mIsDefault); @@ -213,6 +243,10 @@ NS_IMETHODIMP nsPrefBranch::GetIntPref(const char *aPrefName, PRInt32 *_retval) NS_IMETHODIMP nsPrefBranch::SetIntPref(const char *aPrefName, PRInt32 aValue) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot set pref from content process"); @@ -227,6 +261,10 @@ NS_IMETHODIMP nsPrefBranch::SetIntPref(const char *aPrefName, PRInt32 aValue) NS_IMETHODIMP nsPrefBranch::GetComplexValue(const char *aPrefName, const nsIID & aType, void **_retval) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG(aPrefName); nsresult rv; @@ -388,6 +426,10 @@ NS_IMETHODIMP nsPrefBranch::GetComplexValue(const char *aPrefName, const nsIID & NS_IMETHODIMP nsPrefBranch::SetComplexValue(const char *aPrefName, const nsIID & aType, nsISupports *aValue) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot set pref from content process"); @@ -479,6 +521,10 @@ NS_IMETHODIMP nsPrefBranch::SetComplexValue(const char *aPrefName, const nsIID & NS_IMETHODIMP nsPrefBranch::ClearUserPref(const char *aPrefName) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot set pref from content process"); @@ -493,6 +539,10 @@ NS_IMETHODIMP nsPrefBranch::ClearUserPref(const char *aPrefName) NS_IMETHODIMP nsPrefBranch::PrefHasUserValue(const char *aPrefName, PRBool *_retval) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG_POINTER(_retval); NS_ENSURE_ARG(aPrefName); const char *pref = getPrefName(aPrefName); @@ -502,6 +552,10 @@ NS_IMETHODIMP nsPrefBranch::PrefHasUserValue(const char *aPrefName, PRBool *_ret NS_IMETHODIMP nsPrefBranch::LockPref(const char *aPrefName) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot lock pref from content process"); @@ -516,6 +570,10 @@ NS_IMETHODIMP nsPrefBranch::LockPref(const char *aPrefName) NS_IMETHODIMP nsPrefBranch::PrefIsLocked(const char *aPrefName, PRBool *_retval) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot check lock pref from content process"); @@ -532,6 +590,10 @@ NS_IMETHODIMP nsPrefBranch::PrefIsLocked(const char *aPrefName, PRBool *_retval) NS_IMETHODIMP nsPrefBranch::UnlockPref(const char *aPrefName) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot unlock pref from content process"); @@ -552,6 +614,10 @@ NS_IMETHODIMP nsPrefBranch::ResetBranch(const char *aStartingAt) NS_IMETHODIMP nsPrefBranch::DeleteBranch(const char *aStartingAt) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (GetContentChild()) { NS_ERROR("cannot set pref from content process"); @@ -566,6 +632,10 @@ NS_IMETHODIMP nsPrefBranch::DeleteBranch(const char *aStartingAt) NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + char **outArray; PRInt32 numPrefs; PRInt32 dwIndex; @@ -625,6 +695,10 @@ NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCou NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObserver, PRBool aHoldWeak) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + PrefCallback *pCallback; const char *pref; @@ -670,6 +744,10 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aObserver) { + if (NS_UNLIKELY(!nsPrefService::CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + NS_ENSURE_ARG(aDomain); NS_ENSURE_ARG(aObserver); diff --git a/modules/libpref/src/nsPrefService.cpp b/modules/libpref/src/nsPrefService.cpp index 760d3c5a110..05cc53ea389 100644 --- a/modules/libpref/src/nsPrefService.cpp +++ b/modules/libpref/src/nsPrefService.cpp @@ -46,6 +46,7 @@ #include "nsAppDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h" #include "nsICategoryManager.h" +#include "nsIConsoleService.h" #include "nsCategoryManagerUtils.h" #include "nsNetUtil.h" #include "nsIFile.h" @@ -60,6 +61,7 @@ #include "nsCOMArray.h" #include "nsXPCOMCID.h" #include "nsAutoPtr.h" +#include "nsThreadUtils.h" #include "nsQuickSort.h" #include "prmem.h" @@ -219,6 +221,10 @@ NS_IMETHODIMP nsPrefService::Observe(nsISupports *aSubject, const char *aTopic, NS_IMETHODIMP nsPrefService::ReadUserPrefs(nsIFile *aFile) { + if (NS_UNLIKELY(!CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (XRE_GetProcessType() == GeckoProcessType_Content) { NS_ERROR("cannot load prefs from content process"); @@ -242,6 +248,10 @@ NS_IMETHODIMP nsPrefService::ReadUserPrefs(nsIFile *aFile) NS_IMETHODIMP nsPrefService::ResetPrefs() { + if (NS_UNLIKELY(!CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (XRE_GetProcessType() == GeckoProcessType_Content) { NS_ERROR("cannot set prefs from content process"); @@ -260,6 +270,10 @@ NS_IMETHODIMP nsPrefService::ResetPrefs() NS_IMETHODIMP nsPrefService::ResetUserPrefs() { + if (NS_UNLIKELY(!CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (XRE_GetProcessType() == GeckoProcessType_Content) { NS_ERROR("cannot set prefs from content process"); @@ -273,6 +287,10 @@ NS_IMETHODIMP nsPrefService::ResetUserPrefs() NS_IMETHODIMP nsPrefService::SavePrefFile(nsIFile *aFile) { + if (NS_UNLIKELY(!CheckAndLogBackgroundThreadUse())) { + return NS_ERROR_UNEXPECTED; + } + #ifdef MOZ_IPC if (XRE_GetProcessType() == GeckoProcessType_Content) { NS_ERROR("cannot save prefs from content process"); @@ -361,6 +379,10 @@ NS_IMETHODIMP nsPrefService::MirrorPreferences(nsTArray cs = + do_GetService("@mozilla.org/consoleservice;1"); + if (cs) { + (void)cs->LogStringMessage(NS_LITERAL_STRING( + "Invalid use of the preferences on a background thread!" + ).get()); + } + return false; +} diff --git a/modules/libpref/src/nsPrefService.h b/modules/libpref/src/nsPrefService.h index 9cab286bfac..e82b2e381a2 100644 --- a/modules/libpref/src/nsPrefService.h +++ b/modules/libpref/src/nsPrefService.h @@ -67,7 +67,13 @@ public: virtual ~nsPrefService(); nsresult Init(); - + + /** + * Checks to make sure we are on the main thread and log if we are not. + * + * @returns true if on the main thread, and false otherwise. + */ + static bool CheckAndLogBackgroundThreadUse(); protected: nsresult NotifyServiceObservers(const char *aSubject); nsresult UseDefaultPrefFile();