Bug 1960221 - Remove the aNeedsToCache parameter from nsLanguageAtomService::GetLanguageGroup, and simplify callers. r=emilio

We don't need this param; it should be safe to call the method from any thread
and just rely on its internal locking to protect the cache.

Differential Revision: https://phabricator.services.mozilla.com/D245357
This commit is contained in:
Jonathan Kew
2025-04-13 19:25:00 +00:00
parent 6bb4438d60
commit 41983aec3b
6 changed files with 37 additions and 89 deletions

View File

@@ -2149,8 +2149,7 @@ static void GetSystemFontList(nsTArray<nsString>& aListOfFonts,
// add the lang to the pattern
nsAutoCString fcLang;
gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
pfl->GetSampleLangForGroup(aLangGroup, fcLang,
/*aForFontEnumerationThread*/ true);
pfl->GetSampleLangForGroup(aLangGroup, fcLang);
if (!fcLang.IsEmpty()) {
FcPatternAddString(pat, FC_LANG, ToFcChar8Ptr(fcLang.get()));
}
@@ -2771,8 +2770,7 @@ const MozLangGroupData MozLangGroups[] = {
bool gfxFcPlatformFontList::TryLangForGroup(const nsACString& aOSLang,
nsAtom* aLangGroup,
nsACString& aFcLang,
bool aForFontEnumerationThread) {
nsACString& aFcLang) {
// Truncate at '.' or '@' from aOSLang, and convert '_' to '-'.
// aOSLang is in the form "language[_territory][.codeset][@modifier]".
// fontconfig takes languages in the form "language-territory".
@@ -2798,24 +2796,12 @@ bool gfxFcPlatformFontList::TryLangForGroup(const nsACString& aOSLang,
++pos;
}
if (!aForFontEnumerationThread) {
nsAtom* atom = mLangService->LookupLanguage(aFcLang);
return atom == aLangGroup;
}
// If we were called by the font enumeration thread, we can't use
// mLangService->LookupLanguage because it is not thread-safe.
// Use GetUncachedLanguageGroup to avoid unsafe access to the lang-group
// mapping cache hashtable.
nsAutoCString lowered(aFcLang);
ToLowerCase(lowered);
RefPtr<nsAtom> lang = NS_Atomize(lowered);
RefPtr<nsAtom> group = mLangService->GetUncachedLanguageGroup(lang);
return group.get() == aLangGroup;
}
void gfxFcPlatformFontList::GetSampleLangForGroup(
nsAtom* aLanguage, nsACString& aLangStr, bool aForFontEnumerationThread) {
void gfxFcPlatformFontList::GetSampleLangForGroup(nsAtom* aLanguage,
nsACString& aLangStr) {
aLangStr.Truncate();
if (!aLanguage) {
return;
@@ -2850,8 +2836,7 @@ void gfxFcPlatformFontList::GetSampleLangForGroup(
for (const char* pos = languages; true; ++pos) {
if (*pos == '\0' || *pos == separator) {
if (languages < pos &&
TryLangForGroup(Substring(languages, pos), aLanguage, aLangStr,
aForFontEnumerationThread)) {
TryLangForGroup(Substring(languages, pos), aLanguage, aLangStr)) {
return;
}
@@ -2864,8 +2849,8 @@ void gfxFcPlatformFontList::GetSampleLangForGroup(
}
}
const char* ctype = setlocale(LC_CTYPE, nullptr);
if (ctype && TryLangForGroup(nsDependentCString(ctype), aLanguage, aLangStr,
aForFontEnumerationThread)) {
if (ctype &&
TryLangForGroup(nsDependentCString(ctype), aLanguage, aLangStr)) {
return;
}

View File

@@ -308,11 +308,7 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
}
// map lang group ==> lang string
// When aForFontEnumerationThread is true, this method will avoid using
// LanguageService::LookupLanguage, because it is not safe for off-main-
// thread use (except by stylo traversal, which does the necessary locking)
void GetSampleLangForGroup(nsAtom* aLanguage, nsACString& aLangStr,
bool aForFontEnumerationThread = false);
void GetSampleLangForGroup(nsAtom* aLanguage, nsACString& aLangStr);
protected:
virtual ~gfxFcPlatformFontList();
@@ -361,7 +357,7 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
// helper method for finding an appropriate lang string
bool TryLangForGroup(const nsACString& aOSLang, nsAtom* aLangGroup,
nsACString& aLang, bool aForFontEnumerationThread);
nsACString& aLang);
#ifdef MOZ_BUNDLED_FONTS
void ActivateBundledFonts();

View File

@@ -153,15 +153,12 @@ nsAtom* nsLanguageAtomService::GetLocaleLanguage() {
return mLocaleLanguage;
}
nsStaticAtom* nsLanguageAtomService::GetLanguageGroup(nsAtom* aLanguage,
bool* aNeedsToCache) {
if (aNeedsToCache) {
nsStaticAtom* nsLanguageAtomService::GetLanguageGroup(nsAtom* aLanguage) {
{
AutoReadLock lock(mLock);
if (nsStaticAtom* atom = mLangToGroup.Get(aLanguage)) {
return atom;
}
*aNeedsToCache = true;
return nullptr;
}
AutoWriteLock lock(mLock);

View File

@@ -36,26 +36,15 @@ class nsLanguageAtomService final {
already_AddRefed<nsAtom> LookupCharSet(NotNull<const Encoding*> aCharSet);
nsAtom* GetLocaleLanguage();
// Returns the language group that the specified language is a part of.
//
// aNeedsToCache is used for two things. If null, it indicates that
// the nsLanguageAtomService is safe to cache the result of the
// language group lookup, either because we're on the main thread,
// or because we're on a style worker thread but the font lock has
// been acquired. If non-null, it indicates that it's not safe to
// cache the result of the language group lookup (because we're on
// a style worker thread without the lock acquired). In this case,
// GetLanguageGroup will store true in *aNeedsToCache true if we
// would have cached the result of a new lookup, and false if we
// were able to use an existing cached result. Thus, callers that
// get a true *aNeedsToCache outparam value should make an effort
// to re-call GetLanguageGroup when it is safe to cache, to avoid
// recomputing the language group again later.
nsStaticAtom* GetLanguageGroup(nsAtom* aLanguage,
bool* aNeedsToCache = nullptr);
nsStaticAtom* GetUncachedLanguageGroup(nsAtom* aLanguage) const;
// Returns the language group that the specified language is a part of,
// using a cache to avoid repeatedly doing full lookups.
nsStaticAtom* GetLanguageGroup(nsAtom* aLanguage);
private:
// The core implementation of lang-tag to language-group lookup. (Now used
// only internally by GetLanguageGroup.)
nsStaticAtom* GetUncachedLanguageGroup(nsAtom* aLanguage) const;
static mozilla::StaticAutoPtr<nsLanguageAtomService> sLangAtomService;
nsTHashMap<RefPtr<nsAtom>, nsStaticAtom*> mLangToGroup MOZ_GUARDED_BY(mLock);

View File

@@ -199,30 +199,19 @@ void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
}
}
nsStaticAtom* StaticPresData::GetLangGroup(nsAtom* aLanguage,
bool* aNeedsToCache) const {
nsStaticAtom* langGroupAtom =
mLangService->GetLanguageGroup(aLanguage, aNeedsToCache);
nsStaticAtom* StaticPresData::GetLangGroup(nsAtom* aLanguage) const {
nsStaticAtom* langGroupAtom = mLangService->GetLanguageGroup(aLanguage);
// Assume x-western is safe...
return langGroupAtom ? langGroupAtom : nsGkAtoms::x_western;
}
nsStaticAtom* StaticPresData::GetUncachedLangGroup(nsAtom* aLanguage) const {
nsStaticAtom* langGroupAtom =
mLangService->GetUncachedLanguageGroup(aLanguage);
return langGroupAtom ? langGroupAtom : nsGkAtoms::x_western;
}
const LangGroupFontPrefs* StaticPresData::GetFontPrefsForLang(
nsAtom* aLanguage, bool* aNeedsToCache) {
// Get language group for aLanguage:
MOZ_ASSERT(aLanguage);
MOZ_ASSERT(mLangService);
nsStaticAtom* langGroupAtom = GetLangGroup(aLanguage, aNeedsToCache);
if (aNeedsToCache && *aNeedsToCache) {
return nullptr;
}
nsStaticAtom* langGroupAtom = GetLangGroup(aLanguage);
if (!aNeedsToCache) {
AssertIsMainThreadOrServoFontMetricsLocked();

View File

@@ -113,28 +113,8 @@ class StaticPresData {
/**
* Given a language, get the language group name, which can
* be used as an argument to LangGroupFontPrefs::Initialize()
*
* aNeedsToCache is used for two things. If null, it indicates that
* the nsLanguageAtomService is safe to cache the result of the
* language group lookup, either because we're on the main thread,
* or because we're on a style worker thread but the font lock has
* been acquired. If non-null, it indicates that it's not safe to
* cache the result of the language group lookup (because we're on
* a style worker thread without the lock acquired). In this case,
* GetLanguageGroup will store true in *aNeedsToCache true if we
* would have cached the result of a new lookup, and false if we
* were able to use an existing cached result. Thus, callers that
* get a true *aNeedsToCache outparam value should make an effort
* to re-call GetLanguageGroup when it is safe to cache, to avoid
* recomputing the language group again later.
*/
nsStaticAtom* GetLangGroup(nsAtom* aLanguage,
bool* aNeedsToCache = nullptr) const;
/**
* Same as GetLangGroup, but will not cache the result
*/
nsStaticAtom* GetUncachedLangGroup(nsAtom* aLanguage) const;
nsStaticAtom* GetLangGroup(nsAtom* aLanguage) const;
/**
* Fetch the user's font preferences for the given aLanguage's
@@ -150,7 +130,19 @@ class StaticPresData {
* with an additional per-session cache that new callers can use if they don't
* have a PresContext.
*
* See comment on GetLangGroup for the usage of aNeedsToCache.
* aNeedsToCache is used for two things. If null, it indicates that
* it is safe for the StaticPresData to cache the result of the
* prefs lookup, either because we're on the main thread,
* or because we're on a style worker thread but the font lock has
* been acquired. If non-null, it indicates that it's not safe to
* cache the result of the prefs lookup (because we're on
* a style worker thread without the lock acquired). In this case,
* GetFontPrefsForLang will store true in *aNeedsToCache true if we
* would have cached the result of a new lookup, and false if we
* were able to use an existing cached result. Thus, callers that
* get a true *aNeedsToCache outparam value should make an effort
* to re-call GetFontPrefsForLang when it is safe to cache, to avoid
* recomputing the prefs again later.
*/
const LangGroupFontPrefs* GetFontPrefsForLang(nsAtom* aLanguage,
bool* aNeedsToCache = nullptr);