Bug 589905 - Cache remote-preferences to improve performance. r=dwitte. a=blocking-fennec

--HG--
extra : rebase_source : 327ae1b240a0535c2ec61eb3bce15df302d83987
This commit is contained in:
Doug Turner 2010-09-27 14:23:35 -07:00
parent c9fbf062a8
commit f96b653ce0
8 changed files with 84 additions and 275 deletions

View File

@ -180,101 +180,10 @@ ContentParent::IsAlive()
}
bool
ContentParent::RecvGetPrefType(const nsCString& prefName,
PRInt32* retValue, nsresult* rv)
{
*retValue = 0;
EnsurePrefService();
*rv = mPrefService->GetPrefType(prefName.get(), retValue);
return true;
}
bool
ContentParent::RecvGetBoolPref(const nsCString& prefName,
PRBool* retValue, nsresult* rv)
{
*retValue = PR_FALSE;
EnsurePrefService();
*rv = mPrefService->GetBoolPref(prefName.get(), retValue);
return true;
}
bool
ContentParent::RecvGetIntPref(const nsCString& prefName,
PRInt32* retValue, nsresult* rv)
{
*retValue = 0;
EnsurePrefService();
*rv = mPrefService->GetIntPref(prefName.get(), retValue);
return true;
}
bool
ContentParent::RecvGetCharPref(const nsCString& prefName,
nsCString* retValue, nsresult* rv)
ContentParent::RecvReadPrefs(nsCString* prefs)
{
EnsurePrefService();
*rv = mPrefService->GetCharPref(prefName.get(), getter_Copies(*retValue));
return true;
}
bool
ContentParent::RecvGetPrefLocalizedString(const nsCString& prefName,
nsString* retValue, nsresult* rv)
{
EnsurePrefService();
nsCOMPtr<nsIPrefLocalizedString> string;
*rv = mPrefService->GetComplexValue(prefName.get(),
NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(string));
if (NS_SUCCEEDED(*rv))
string->GetData(getter_Copies(*retValue));
return true;
}
bool
ContentParent::RecvPrefHasUserValue(const nsCString& prefName,
PRBool* retValue, nsresult* rv)
{
*retValue = PR_FALSE;
EnsurePrefService();
*rv = mPrefService->PrefHasUserValue(prefName.get(), retValue);
return true;
}
bool
ContentParent::RecvPrefIsLocked(const nsCString& prefName,
PRBool* retValue, nsresult* rv)
{
*retValue = PR_FALSE;
EnsurePrefService();
*rv = mPrefService->PrefIsLocked(prefName.get(), retValue);
return true;
}
bool
ContentParent::RecvGetChildList(const nsCString& domain,
nsTArray<nsCString>* list, nsresult* rv)
{
EnsurePrefService();
PRUint32 count;
char **childArray;
*rv = mPrefService->GetChildList(domain.get(), &count, &childArray);
if (NS_SUCCEEDED(*rv)) {
list->SetCapacity(count);
for (PRUint32 i = 0; i < count; ++i)
*(list->AppendElement()) = childArray[i];
}
mPrefService->SerializePreferences(*prefs);
return true;
}

View File

@ -125,29 +125,7 @@ private:
const PRInt64& aContentLength);
virtual bool DeallocPExternalHelperApp(PExternalHelperAppParent* aService);
virtual bool RecvGetPrefType(const nsCString& prefName,
PRInt32* retValue, nsresult* rv);
virtual bool RecvGetBoolPref(const nsCString& prefName,
PRBool* retValue, nsresult* rv);
virtual bool RecvGetIntPref(const nsCString& prefName,
PRInt32* retValue, nsresult* rv);
virtual bool RecvGetCharPref(const nsCString& prefName,
nsCString* retValue, nsresult* rv);
virtual bool RecvGetPrefLocalizedString(const nsCString& prefName,
nsString* retValue, nsresult* rv);
virtual bool RecvPrefHasUserValue(const nsCString& prefName,
PRBool* retValue, nsresult* rv);
virtual bool RecvPrefIsLocked(const nsCString& prefName,
PRBool* retValue, nsresult* rv);
virtual bool RecvGetChildList(const nsCString& domain,
nsTArray<nsCString>* list, nsresult* rv);
virtual bool RecvReadPrefs(nsCString* prefs);
virtual bool RecvTestPermission(const IPC::URI& aUri,
const nsCString& aType,
@ -189,7 +167,7 @@ private:
nsCOMPtr<nsIThreadObserver> mOldObserver;
bool mIsAlive;
nsCOMPtr<nsIPrefBranch> mPrefService;
nsCOMPtr<nsIPrefServiceInternal> mPrefService;
nsCOMPtr<nsIPermissionManager> mPermissionService;
};

View File

@ -93,14 +93,7 @@ parent:
async LoadURIExternal(URI uri);
// PrefService messages
sync GetPrefType(nsCString prefName) returns (PRInt32 retValue, nsresult rv);
sync GetBoolPref(nsCString prefName) returns (PRBool retValue, nsresult rv);
sync GetIntPref(nsCString prefName) returns (PRInt32 retValue, nsresult rv);
sync GetCharPref(nsCString prefName) returns (nsCString retValue, nsresult rv);
sync GetPrefLocalizedString(nsCString prefName) returns (nsString retValue, nsresult rv);
sync PrefHasUserValue(nsCString prefName) returns (PRBool retValue, nsresult rv);
sync PrefIsLocked(nsCString prefName) returns (PRBool retValue, nsresult rv);
sync GetChildList(nsCString domain) returns (nsCString[] list, nsresult rv);
sync ReadPrefs() returns (nsCString retValue);
// PermissionsManager messages
sync TestPermission(URI uri, nsCString type, PRBool exact) returns (PRUint32 retValue);

View File

@ -153,7 +153,7 @@ interface nsIPrefService : nsISupports
};
[scriptable, uuid(00162579-0687-478d-8a52-f49714d4c1be)]
[scriptable, uuid(37577836-e3fc-4a5e-b5d1-92a17fe0e7f7)]
interface nsIPrefServiceInternal : nsISupports
{
/**
@ -168,6 +168,8 @@ interface nsIPrefServiceInternal : nsISupports
* @see readUserPrefs
*/
void readExtensionPrefs(in nsILocalFile aFile);
ACString serializePreferences();
};
%{C++

View File

@ -151,17 +151,6 @@ NS_IMETHODIMP nsPrefBranch::GetRoot(char **aRoot)
NS_IMETHODIMP nsPrefBranch::GetPrefType(const char *aPrefName, PRInt32 *_retval)
{
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
PRInt32 retval;
cpc->SendGetPrefType(nsDependentCString(getPrefName(aPrefName)), &retval, &rv);
if (NS_SUCCEEDED(rv))
*_retval = retval;
return rv;
}
#endif
const char *pref = getPrefName(aPrefName);
*_retval = PREF_GetPrefType(pref);
return NS_OK;
@ -169,17 +158,6 @@ NS_IMETHODIMP nsPrefBranch::GetPrefType(const char *aPrefName, PRInt32 *_retval)
NS_IMETHODIMP nsPrefBranch::GetBoolPref(const char *aPrefName, PRBool *_retval)
{
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
PRBool retval;
cpc->SendGetBoolPref(nsDependentCString(getPrefName(aPrefName)), &retval, &rv);
if (NS_SUCCEEDED(rv))
*_retval = retval;
return rv;
}
#endif
const char *pref = getPrefName(aPrefName);
return PREF_GetBoolPref(pref, _retval, mIsDefault);
}
@ -199,19 +177,6 @@ NS_IMETHODIMP nsPrefBranch::SetBoolPref(const char *aPrefName, PRInt32 aValue)
NS_IMETHODIMP nsPrefBranch::GetCharPref(const char *aPrefName, char **_retval)
{
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
nsCAutoString prefValue;
cpc->SendGetCharPref(nsDependentCString(getPrefName(aPrefName)),
&prefValue, &rv);
if (NS_SUCCEEDED(rv)) {
*_retval = strdup(prefValue.get());
}
return rv;
}
#endif
const char *pref = getPrefName(aPrefName);
return PREF_CopyCharPref(pref, _retval, mIsDefault);
}
@ -231,17 +196,6 @@ NS_IMETHODIMP nsPrefBranch::SetCharPref(const char *aPrefName, const char *aValu
NS_IMETHODIMP nsPrefBranch::GetIntPref(const char *aPrefName, PRInt32 *_retval)
{
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
PRInt32 retval;
cpc->SendGetIntPref(nsDependentCString(getPrefName(aPrefName)), &retval, &rv);
if (NS_SUCCEEDED(rv))
*_retval = retval;
return rv;
}
#endif
const char *pref = getPrefName(aPrefName);
return PREF_GetIntPref(pref, _retval, mIsDefault);
}
@ -269,21 +223,6 @@ NS_IMETHODIMP nsPrefBranch::GetComplexValue(const char *aPrefName, const nsIID &
nsCOMPtr<nsIPrefLocalizedString> theString(do_CreateInstance(NS_PREFLOCALIZEDSTRING_CONTRACTID, &rv));
if (NS_FAILED(rv)) return rv;
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsAutoString prefValue;
rv = NS_ERROR_NOT_AVAILABLE;
cpc->SendGetPrefLocalizedString(nsDependentCString(getPrefName(aPrefName)),
&prefValue, &rv);
if (NS_FAILED(rv)) return rv;
theString->SetData(prefValue.get());
theString.forget(reinterpret_cast<nsIPrefLocalizedString**>(_retval));
return rv;
}
#endif
const char *pref = getPrefName(aPrefName);
PRBool bNeedDefault = PR_FALSE;
@ -539,17 +478,6 @@ NS_IMETHODIMP nsPrefBranch::PrefHasUserValue(const char *aPrefName, PRBool *_ret
{
NS_ENSURE_ARG_POINTER(_retval);
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
PRBool retval;
cpc->SendPrefHasUserValue(nsDependentCString(getPrefName(aPrefName)), &retval, &rv);
if (NS_SUCCEEDED(rv))
*_retval = retval;
return rv;
}
#endif
const char *pref = getPrefName(aPrefName);
*_retval = PREF_HasUserPref(pref);
return NS_OK;
@ -570,19 +498,14 @@ NS_IMETHODIMP nsPrefBranch::LockPref(const char *aPrefName)
NS_IMETHODIMP nsPrefBranch::PrefIsLocked(const char *aPrefName, PRBool *_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
PRBool retval;
cpc->SendPrefIsLocked(nsDependentCString(getPrefName(aPrefName)), &retval, &rv);
if (NS_SUCCEEDED(rv))
*_retval = retval;
return rv;
if (GetContentChild()) {
NS_ERROR("cannot check lock pref from content process");
return NS_ERROR_NOT_AVAILABLE;
}
#endif
NS_ENSURE_ARG_POINTER(_retval);
const char *pref = getPrefName(aPrefName);
*_retval = PREF_PrefIsLocked(pref);
return NS_OK;
@ -635,26 +558,15 @@ NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCou
*aChildArray = nsnull;
*aCount = 0;
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
nsresult rv = NS_ERROR_NOT_AVAILABLE;
cpc->SendGetChildList(nsDependentCString(getPrefName(aStartingAt)),
&prefArray, &rv);
if (NS_FAILED(rv)) return rv;
if (!gHashTable.ops)
return NS_ERROR_NOT_INITIALIZED;
} else
#endif
{
if (!gHashTable.ops)
return NS_ERROR_NOT_INITIALIZED;
// this will contain a list of all the pref name strings
// allocate on the stack for speed
ed.parent = getPrefName(aStartingAt);
ed.pref_list = &prefArray;
PL_DHashTableEnumerate(&gHashTable, pref_enumChild, &ed);
}
// this will contain a list of all the pref name strings
// allocate on the stack for speed
ed.parent = getPrefName(aStartingAt);
ed.pref_list = &prefArray;
PL_DHashTableEnumerate(&gHashTable, pref_enumChild, &ed);
// now that we've built up the list, run the callback on
// all the matching elements
@ -698,12 +610,6 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser
NS_ENSURE_ARG_POINTER(aDomain);
NS_ENSURE_ARG_POINTER(aObserver);
#ifdef MOZ_IPC
if (ContentChild* cpc = GetContentChild()) {
return cpc->AddRemotePrefObserver(nsDependentCString(aDomain), mPrefRoot, aObserver, aHoldWeak);
}
#endif
// hold a weak reference to the observer if so requested
if (aHoldWeak) {
nsCOMPtr<nsISupportsWeakReference> weakRefFactory = do_QueryInterface(aObserver);
@ -748,20 +654,6 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
nsresult rv = NS_OK;
#ifdef MOZ_IPC
if (XRE_GetProcessType() == GeckoProcessType_Content) {
ContentChild *cpc = ContentChild::GetSingleton();
// In case cpc doesn't exist here, we're silently returning (instead of
// asserting), because the child process is likely to be null
// when this is called during xpcom-shutdown.
if (cpc)
rv = cpc->RemoveRemotePrefObserver(nsDependentCString(aDomain),
mPrefRoot,
aObserver);
return rv;
}
#endif
// If we're in the middle of a call to freeObserverList, don't process this
// RemoveObserver call -- the observer in question will be removed soon, if
// it hasn't been already.
@ -799,16 +691,6 @@ NS_IMETHODIMP nsPrefBranch::Observe(nsISupports *aSubject, const char *aTopic, c
/* static */
nsresult nsPrefBranch::NotifyObserver(const char *newpref, void *data)
{
#ifdef MOZ_IPC
if (GetContentChild()) {
// We shouldn't ever get here, since we never register NotifyObserver in the
// content process
NS_NOTREACHED("Remote prefs observation should be done from the \
chrome process!");
return NS_OK;
}
#endif
PrefCallback *pCallback = (PrefCallback *)data;
nsCOMPtr<nsIObserver> observer = pCallback->GetObserver();

View File

@ -38,6 +38,7 @@
* ***** END LICENSE BLOCK ***** */
#ifdef MOZ_IPC
#include "mozilla/dom/ContentChild.h"
#include "nsXULAppAPI.h"
#endif
@ -131,14 +132,6 @@ nsresult nsPrefService::Init()
mRootBranch = (nsIPrefBranch2 *)rootBranch;
#ifdef MOZ_IPC
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// We're done. Let the prefbranch remote requests.
return NS_OK;
}
#endif
nsXPIDLCString lockFileName;
nsresult rv;
rv = PREF_Init();
@ -147,6 +140,24 @@ nsresult nsPrefService::Init()
rv = pref_InitInitialObjects();
NS_ENSURE_SUCCESS(rv, rv);
#ifdef MOZ_IPC
using mozilla::dom::ContentChild;
if (XRE_GetProcessType() == GeckoProcessType_Content) {
ContentChild* cpc = ContentChild::GetSingleton();
nsCAutoString prefs;
cpc->SendReadPrefs(&prefs);
PrefParseState ps;
PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
nsresult rv = PREF_ParseBuf(&ps, prefs.get(), prefs.Length());
PREF_FinalizeParseState(&ps);
return rv;
}
#endif
nsXPIDLCString lockFileName;
/*
* The following is a small hack which will allow us to only load the library
* which supports the netscape.cfg file if the preference is defined. We
@ -322,6 +333,32 @@ NS_IMETHODIMP nsPrefService::ReadExtensionPrefs(nsILocalFile *aFile)
return rv;
}
NS_IMETHODIMP nsPrefService::SerializePreferences(nsACString& prefs)
{
char** valueArray = (char **)PR_Calloc(sizeof(char *), gHashTable.entryCount);
if (!valueArray)
return NS_ERROR_OUT_OF_MEMORY;
pref_saveArgs saveArgs;
saveArgs.prefArray = valueArray;
saveArgs.saveTypes = SAVE_ALL_AND_DEFAULTS;
// get the lines that we're supposed to be writing
PL_DHashTableEnumerate(&gHashTable, pref_savePref, &saveArgs);
char** walker = valueArray;
for (PRUint32 valueIdx = 0; valueIdx < gHashTable.entryCount; valueIdx++, walker++) {
if (*walker) {
prefs.Append(*walker);
prefs.Append(NS_LINEBREAK);
NS_Free(*walker);
}
}
PR_Free(valueArray);
return NS_OK;
}
NS_IMETHODIMP nsPrefService::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
{
nsresult rv;

View File

@ -311,7 +311,6 @@ PREF_SetBoolPref(const char *pref_name, PRBool value, PRBool set_default)
return pref_HashPref(pref_name, pref, PREF_BOOL, set_default);
}
PLDHashOperator
pref_savePref(PLDHashTable *table, PLDHashEntryHdr *heh, PRUint32 i, void *arg)
{
@ -323,6 +322,8 @@ pref_savePref(PLDHashTable *table, PLDHashEntryHdr *heh, PRUint32 i, void *arg)
return PL_DHASH_NEXT;
nsCAutoString prefValue;
nsCAutoString prefPrefix;
prefPrefix.Assign(NS_LITERAL_CSTRING("user_pref(\""));
// where we're getting our pref from
PrefValue* sourcePref;
@ -330,11 +331,17 @@ pref_savePref(PLDHashTable *table, PLDHashEntryHdr *heh, PRUint32 i, void *arg)
if (PREF_HAS_USER_VALUE(pref) &&
pref_ValueChanged(pref->defaultPref,
pref->userPref,
(PrefType) PREF_TYPE(pref)))
(PrefType) PREF_TYPE(pref))) {
sourcePref = &pref->userPref;
else
// do not save default prefs that haven't changed
return PL_DHASH_NEXT;
} else {
if (argData->saveTypes == SAVE_ALL_AND_DEFAULTS) {
prefPrefix.Assign(NS_LITERAL_CSTRING("pref(\""));
sourcePref = &pref->defaultPref;
}
else
// do not save default prefs that haven't changed
return PL_DHASH_NEXT;
}
// strings are in quotes!
if (pref->flags & PREF_STRING) {
@ -352,11 +359,12 @@ pref_savePref(PLDHashTable *table, PLDHashEntryHdr *heh, PRUint32 i, void *arg)
nsCAutoString prefName;
str_escape(pref->key, prefName);
argData->prefArray[i] = ToNewCString(NS_LITERAL_CSTRING("user_pref(\"") +
prefName +
NS_LITERAL_CSTRING("\", ") +
prefValue +
NS_LITERAL_CSTRING(");"));
argData->prefArray[i] = ToNewCString(prefPrefix +
prefName +
NS_LITERAL_CSTRING("\", ") +
prefValue +
NS_LITERAL_CSTRING(");"));
return PL_DHASH_NEXT;
}

View File

@ -40,7 +40,7 @@
extern PLDHashTable gHashTable;
extern PRBool gDirty;
enum pref_SaveTypes { SAVE_NONSHARED, SAVE_SHARED, SAVE_ALL };
enum pref_SaveTypes { SAVE_NONSHARED, SAVE_SHARED, SAVE_ALL, SAVE_ALL_AND_DEFAULTS };
// Passed as the arg to pref_savePref
struct pref_saveArgs {