Avoid deadlock in SkGetFallbackFamilyNameForChar().
The deaklock happened when SkFontHost::CreateTypefaceFromStream() is called
indirectly from SkGetFallbackFamilyNameForChar().
This commits a change that was submitted for review by...
wangxianzhu1 @ https://codereview.appspot.com/6654051/
Review URL: https://codereview.appspot.com/6690044
git-svn-id: http://skia.googlecode.com/svn/trunk@5956 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index 9f1bd56..d46c897 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -1005,6 +1005,7 @@
// ensure that if any value is added to the public enum it is also added here
SK_COMPILE_ASSERT(gFBScriptInfoCount == kFallbackScriptNumber, FBScript_count_mismatch);
+// this function can't be called if the gFamilyHeadAndNameListMutex is already locked
static bool typefaceContainsChar(SkTypeface* face, SkUnichar uni) {
SkPaint paint;
paint.setTypeface(face);
@@ -1015,11 +1016,16 @@
return glyphID != 0;
}
+// this function can't be called if the gFamilyHeadAndNameListMutex is already locked
static SkTypeface* findFallbackTypefaceForChar(SkUnichar uni) {
SkASSERT(gFallbackFonts);
const uint32_t* list = gFallbackFonts;
for (int i = 0; list[i] != 0; i++) {
- SkTypeface* face = find_from_uniqueID(list[i]);
+ SkTypeface* face;
+ {
+ SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
+ face = find_from_uniqueID(list[i]);
+ }
if (typefaceContainsChar(face, uni)) {
return face;
}
@@ -1027,6 +1033,7 @@
return 0;
}
+// this function can't be called if the gFamilyHeadAndNameListMutex is already locked
static SkFontID findFallbackFontIDForChar(SkUnichar uni, SkTypeface::Style style) {
const SkTypeface* tf = findFallbackTypefaceForChar(uni);
if (!tf) {
@@ -1107,13 +1114,16 @@
SkTypeface* SkCreateFallbackTypefaceForChar(SkUnichar uni,
SkTypeface::Style style) {
- SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
- load_system_fonts();
+ {
+ SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
+ load_system_fonts();
+ }
SkTypeface* tf = findFallbackTypefaceForChar(uni);
if (!tf) {
return NULL;
}
+ SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
tf = find_typeface(tf, style);
// we ref(), since the semantic is to return a new instance
tf->ref();
@@ -1122,13 +1132,16 @@
bool SkGetFallbackFamilyNameForChar(SkUnichar uni, SkString* name) {
SkASSERT(name);
- SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
- load_system_fonts();
+ {
+ SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
+ load_system_fonts();
+ }
const SkTypeface* tf = findFallbackTypefaceForChar(uni);
if (!tf) {
return false;
}
+ SkAutoMutexAcquire ac(gFamilyHeadAndNameListMutex);
name->set(find_family_name(tf));
return true;
}