зеркало из https://github.com/mozilla/moz-skia.git
Fix thread unsafe mutex initialization.
BUG=skia:2779 R=robertphillips@google.com, mtklein@google.com, reed@android.com, bsalomon@google.com Author: bungeman@google.com Review URL: https://codereview.chromium.org/419113002
This commit is contained in:
Родитель
6c18c80c86
Коммит
d6aeb6dc8f
|
@ -19,7 +19,7 @@ protected:
|
|||
}
|
||||
|
||||
virtual void onDraw(const int loops, SkCanvas*) {
|
||||
SK_DECLARE_STATIC_MUTEX(mu);
|
||||
SkMutex mu;
|
||||
for (int i = 0; i < loops; i++) {
|
||||
mu.acquire();
|
||||
mu.release();
|
||||
|
|
|
@ -73,9 +73,14 @@ extern bool gPrintInstCount;
|
|||
return gChildren; \
|
||||
} \
|
||||
\
|
||||
static void create_mutex(SkMutex** mutex) { \
|
||||
*mutex = SkNEW(SkMutex); \
|
||||
} \
|
||||
static SkBaseMutex& GetChildrenMutex() { \
|
||||
SK_DECLARE_STATIC_MUTEX(childrenMutex); \
|
||||
return childrenMutex; \
|
||||
static SkMutex* childrenMutex; \
|
||||
SK_DECLARE_STATIC_ONCE(once); \
|
||||
SkOnce(&once, className::SkInstanceCountHelper::create_mutex, &childrenMutex);\
|
||||
return *childrenMutex; \
|
||||
} \
|
||||
\
|
||||
} fInstanceCountHelper; \
|
||||
|
|
|
@ -96,7 +96,6 @@ public:
|
|||
};
|
||||
|
||||
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ...
|
||||
#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = ...
|
||||
*/
|
||||
|
||||
#include SK_MUTEX_PLATFORM_H
|
||||
|
|
|
@ -21,7 +21,7 @@ class SkPath;
|
|||
*/
|
||||
class GrFontDescKey : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkGrDescKey)
|
||||
SK_DECLARE_INST_COUNT(GrFontDescKey)
|
||||
|
||||
typedef uint32_t Hash;
|
||||
|
||||
|
|
|
@ -76,13 +76,13 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gCreateDefaultMutex);
|
||||
SkTypeface* SkTypeface::CreateDefault(int style) {
|
||||
// If backed by fontconfig, it's not safe to call SkFontHost::CreateTypeface concurrently.
|
||||
// To be safe, we serialize here with a mutex so only one call to
|
||||
// CreateTypeface is happening at any given time.
|
||||
// TODO(bungeman, mtklein): This is sad. Make our fontconfig code safe?
|
||||
SK_DECLARE_STATIC_MUTEX(mutex);
|
||||
SkAutoMutexAcquire lock(&mutex);
|
||||
SkAutoMutexAcquire lock(&gCreateDefaultMutex);
|
||||
|
||||
SkTypeface* t = SkFontHost::CreateTypeface(NULL, NULL, (Style)style);
|
||||
return t ? t : SkEmptyTypeface::Create();
|
||||
|
|
|
@ -570,6 +570,7 @@ SkGradientShaderBase::GradientShaderCache* SkGradientShaderBase::refCache(U8CPU
|
|||
return fCache;
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gGradientCacheMutex);
|
||||
/*
|
||||
* Because our caller might rebuild the same (logically the same) gradient
|
||||
* over and over, we'd like to return exactly the same "bitmap" if possible,
|
||||
|
@ -605,11 +606,10 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const {
|
|||
|
||||
///////////////////////////////////
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gMutex);
|
||||
static SkBitmapCache* gCache;
|
||||
// each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp
|
||||
static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
|
||||
SkAutoMutexAcquire ama(gMutex);
|
||||
SkAutoMutexAcquire ama(gGradientCacheMutex);
|
||||
|
||||
if (NULL == gCache) {
|
||||
gCache = SkNEW_ARGS(SkBitmapCache, (MAX_NUM_CACHED_GRADIENT_BITMAPS));
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
class GrDrawTargetCaps : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(Caps)
|
||||
SK_DECLARE_INST_COUNT(GrDrawTargetCaps)
|
||||
|
||||
GrDrawTargetCaps() { this->reset(); }
|
||||
GrDrawTargetCaps(const GrDrawTargetCaps& other) : INHERITED() { *this = other; }
|
||||
|
|
|
@ -892,9 +892,9 @@ SkTDArray<SkPDFFont::FontRec>& SkPDFFont::CanonicalFonts() {
|
|||
return gCanonicalFonts;
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex);
|
||||
// static
|
||||
SkBaseMutex& SkPDFFont::CanonicalFontsMutex() {
|
||||
SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex);
|
||||
return gCanonicalFontsMutex;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,9 +88,9 @@ SkTDArray<SkPDFGraphicState::GSCanonicalEntry>& SkPDFGraphicState::CanonicalPain
|
|||
return gCanonicalPaints;
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex);
|
||||
// static
|
||||
SkBaseMutex& SkPDFGraphicState::CanonicalPaintsMutex() {
|
||||
SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex);
|
||||
return gCanonicalPaintsMutex;
|
||||
}
|
||||
|
||||
|
|
|
@ -664,9 +664,9 @@ SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() {
|
|||
return gCanonicalShaders;
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
|
||||
// static
|
||||
SkBaseMutex& SkPDFShader::CanonicalShadersMutex() {
|
||||
SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
|
||||
return gCanonicalShadersMutex;
|
||||
}
|
||||
|
||||
|
|
|
@ -132,11 +132,11 @@ private:
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gGetSingletonInterfaceMutex);
|
||||
static SkFontConfigInterfaceAndroid* getSingletonInterface() {
|
||||
SK_DECLARE_STATIC_MUTEX(gMutex);
|
||||
static SkFontConfigInterfaceAndroid* gFontConfigInterface;
|
||||
|
||||
SkAutoMutexAcquire ac(gMutex);
|
||||
SkAutoMutexAcquire ac(gGetSingletonInterfaceMutex);
|
||||
if (NULL == gFontConfigInterface) {
|
||||
// load info from a configuration file that we can use to populate the
|
||||
// system/fallback font structures
|
||||
|
|
|
@ -526,9 +526,9 @@ static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theSty
|
|||
return ctFont ? NewFromFontRef(ctFont, familyName, false) : NULL;
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(gGetDefaultFaceMutex);
|
||||
static SkTypeface* GetDefaultFace() {
|
||||
SK_DECLARE_STATIC_MUTEX(gMutex);
|
||||
SkAutoMutexAcquire ma(gMutex);
|
||||
SkAutoMutexAcquire ma(gGetDefaultFaceMutex);
|
||||
|
||||
static SkTypeface* gDefaultFace;
|
||||
|
||||
|
|
|
@ -89,9 +89,11 @@ private:
|
|||
#define SK_BASE_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, SkDEBUGCODE(0) }
|
||||
|
||||
// Using POD-style initialization prevents the generation of a static initializer.
|
||||
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = SK_BASE_MUTEX_INIT
|
||||
|
||||
// Special case used when the static mutex must be available globally.
|
||||
#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = SK_BASE_MUTEX_INIT
|
||||
// Without magic statics there are no thread safety guarantees on initialization
|
||||
// of local statics (even POD).
|
||||
// As a result, it is illegal to SK_DECLARE_STATIC_MUTEX in a function.
|
||||
#define SK_DECLARE_STATIC_MUTEX(name) \
|
||||
static inline void SK_MACRO_APPEND_LINE(name)(){} \
|
||||
static SkBaseMutex name = SK_BASE_MUTEX_INIT
|
||||
|
||||
#endif
|
||||
|
|
|
@ -73,7 +73,9 @@ private:
|
|||
class SkMutex : public SkBaseMutex { };
|
||||
|
||||
// Windows currently provides no documented means of POD initializing a CRITICAL_SECTION.
|
||||
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name
|
||||
#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name
|
||||
// As a result, it is illegal to SK_DECLARE_STATIC_MUTEX in a function.
|
||||
#define SK_DECLARE_STATIC_MUTEX(name) \
|
||||
static inline void SK_MACRO_APPEND_LINE(name)(){} \
|
||||
static SkBaseMutex name
|
||||
|
||||
#endif
|
||||
|
|
|
@ -316,6 +316,8 @@ void ShowTestArray() {
|
|||
}
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(compareDebugOut3);
|
||||
SK_DECLARE_STATIC_MUTEX(compareDebugOut4);
|
||||
static int comparePaths(skiatest::Reporter* reporter, const char* testName, const SkPath& one,
|
||||
const SkPath& scaledOne, const SkPath& two, const SkPath& scaledTwo, SkBitmap& bitmap,
|
||||
const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const SkMatrix& scale) {
|
||||
|
@ -329,13 +331,11 @@ static int comparePaths(skiatest::Reporter* reporter, const char* testName, cons
|
|||
}
|
||||
const int MAX_ERRORS = 8;
|
||||
if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
|
||||
SK_DECLARE_STATIC_MUTEX(compareDebugOut3);
|
||||
SkAutoMutexAcquire autoM(compareDebugOut3);
|
||||
SkDebugf("\n*** this test fails ***\n");
|
||||
showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
|
||||
REPORTER_ASSERT(reporter, 0);
|
||||
} else if (gShowPath || errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
|
||||
SK_DECLARE_STATIC_MUTEX(compareDebugOut4);
|
||||
SkAutoMutexAcquire autoM(compareDebugOut4);
|
||||
showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
|
||||
}
|
||||
|
@ -402,6 +402,7 @@ static void outputToStream(const char* pathStr, const char* pathPrefix, const ch
|
|||
outFile.flush();
|
||||
}
|
||||
|
||||
SK_DECLARE_STATIC_MUTEX(simplifyDebugOut);
|
||||
bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
|
||||
const char* pathStr) {
|
||||
SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
|
||||
|
@ -421,7 +422,6 @@ bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
|
|||
}
|
||||
int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap);
|
||||
if (result && gPathStrAssert) {
|
||||
SK_DECLARE_STATIC_MUTEX(simplifyDebugOut);
|
||||
SkAutoMutexAcquire autoM(simplifyDebugOut);
|
||||
char temp[8192];
|
||||
sk_bzero(temp, sizeof(temp));
|
||||
|
|
Загрузка…
Ссылка в новой задаче