aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-03-31 18:41:30 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-03-31 18:41:30 +0000
commit07421a52d40083cdefc7ab5df6a90495a1d8e785 (patch)
treeb204742905e4c9aaa3364946acd44f333c6f4f65
parentb19bc7f6b99e49b7bb1905282ae52cf4fb80e4e9 (diff)
Add global fontconfig lock.
BUG=skia:2255, skia:1497 NOTRY=true R=bungeman@google.com, mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/219613003 git-svn-id: http://skia.googlecode.com/svn/trunk@13998 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/fonts/SkFontMgr_fontconfig.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp
index bd4c8ddc1d..1d17111b79 100644
--- a/src/fonts/SkFontMgr_fontconfig.cpp
+++ b/src/fonts/SkFontMgr_fontconfig.cpp
@@ -12,12 +12,45 @@
#include "SkMath.h"
#include "SkString.h"
#include "SkTDArray.h"
+#include "SkThread.h"
// for now we pull these in directly. eventually we will solely rely on the
// SkFontConfigInterface instance.
#include <fontconfig/fontconfig.h>
#include <unistd.h>
+namespace {
+
+// Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex.
+// See skia:1497 for background.
+SK_DECLARE_STATIC_MUTEX(gFCMutex);
+static bool gFCSafeToUse;
+
+struct FCLocker {
+ FCLocker() {
+ if (FcGetVersion() < 21091) { // We assume FcGetVersion() has always been thread safe.
+ gFCMutex.acquire();
+ fUnlock = true;
+ } else {
+ fUnlock = false;
+ }
+ gFCSafeToUse = true;
+ }
+
+ ~FCLocker() {
+ gFCSafeToUse = false;
+ if (fUnlock) {
+ gFCMutex.release();
+ }
+ }
+
+private:
+ bool fUnlock;
+};
+
+} // namespace
+
+
// Defined in SkFontHost_FreeType.cpp
bool find_name_and_attributes(SkStream* stream, SkString* name,
SkTypeface::Style* style, bool* isFixedWidth);
@@ -40,6 +73,7 @@ static bool is_lower(char c) {
}
static int get_int(FcPattern* pattern, const char field[]) {
+ SkASSERT(gFCSafeToUse);
int value;
if (FcPatternGetInteger(pattern, field, 0, &value) != FcResultMatch) {
value = SK_MinS32;
@@ -48,6 +82,7 @@ static int get_int(FcPattern* pattern, const char field[]) {
}
static const char* get_name(FcPattern* pattern, const char field[]) {
+ SkASSERT(gFCSafeToUse);
const char* name;
if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch) {
name = "";
@@ -56,6 +91,7 @@ static const char* get_name(FcPattern* pattern, const char field[]) {
}
static bool valid_pattern(FcPattern* pattern) {
+ SkASSERT(gFCSafeToUse);
FcBool is_scalable;
if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch || !is_scalable) {
return false;
@@ -208,6 +244,8 @@ protected:
}
virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVERRIDE {
+ FCLocker lock;
+
FcPattern* pattern = FcPatternCreate();
FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
@@ -284,6 +322,7 @@ protected:
virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
unsigned styleBits) const SK_OVERRIDE {
+ FCLocker lock;
return FontConfigTypeface::LegacyCreateTypeface(NULL, familyName,
(SkTypeface::Style)styleBits);
}