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
This commit is contained in:
parent
b19bc7f6b9
commit
07421a52d4
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user