| Index: src/ports/SkFontConfigInterface_direct.cpp
|
| diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp
|
| index d384f707b1812d629e0481aaf67816899d67b04c..d6fa96a46cfa5c418516a860edbfc9af9937a385 100644
|
| --- a/src/ports/SkFontConfigInterface_direct.cpp
|
| +++ b/src/ports/SkFontConfigInterface_direct.cpp
|
| @@ -24,6 +24,56 @@
|
| #include <fontconfig/fontconfig.h>
|
| #include <unistd.h>
|
|
|
| +#ifdef SK_DEBUG
|
| +# include "SkTLS.h"
|
| +#endif
|
| +
|
| +namespace {
|
| +
|
| +// Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a global mutex.
|
| +// See https://bug.skia.org/1497 for background.
|
| +SK_DECLARE_STATIC_MUTEX(gFCMutex);
|
| +
|
| +#ifdef SK_DEBUG
|
| +void* CreateThreadFcLocked() { return new bool(false); }
|
| +void DeleteThreadFcLocked(void* v) { delete static_cast<bool*>(v); }
|
| +# define THREAD_FC_LOCKED \
|
| + static_cast<bool*>(SkTLS::Get(CreateThreadFcLocked, DeleteThreadFcLocked))
|
| +#endif
|
| +
|
| +struct FCLocker {
|
| + // Assume FcGetVersion() has always been thread safe.
|
| +
|
| + FCLocker() {
|
| + if (FcGetVersion() < 21091) {
|
| + gFCMutex.acquire();
|
| + } else {
|
| + SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED);
|
| + SkASSERT(false == *threadLocked);
|
| + SkDEBUGCODE(*threadLocked = true);
|
| + }
|
| + }
|
| +
|
| + ~FCLocker() {
|
| + AssertHeld();
|
| + if (FcGetVersion() < 21091) {
|
| + gFCMutex.release();
|
| + } else {
|
| + SkDEBUGCODE(*THREAD_FC_LOCKED = false);
|
| + }
|
| + }
|
| +
|
| + static void AssertHeld() { SkDEBUGCODE(
|
| + if (FcGetVersion() < 21091) {
|
| + gFCMutex.assertHeld();
|
| + } else {
|
| + SkASSERT(true == *THREAD_FC_LOCKED);
|
| + }
|
| + ) }
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const {
|
| size_t size = sizeof(fID) + sizeof(fTTCIndex);
|
| size += sizeof(int32_t) + sizeof(int32_t) + sizeof(uint8_t); // weight, width, italic
|
| @@ -448,7 +498,7 @@ static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
|
| #define kMaxFontFamilyLength 2048
|
|
|
| SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() {
|
| - SkAutoMutexAcquire ac(mutex_);
|
| + FCLocker lock;
|
|
|
| FcInit();
|
|
|
| @@ -532,7 +582,7 @@ bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
|
| return false;
|
| }
|
|
|
| - SkAutoMutexAcquire ac(mutex_);
|
| + FCLocker lock;
|
|
|
| FcPattern* pattern = FcPatternCreate();
|
|
|
| @@ -649,7 +699,7 @@ static bool find_name(const SkTDArray<const char*>& list, const char* str) {
|
| }
|
|
|
| SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() {
|
| - SkAutoMutexAcquire ac(mutex_);
|
| + FCLocker lock;
|
|
|
| FcPattern* pat = FcPatternCreate();
|
| SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat);
|
|
|