Bug 1473732 - avoid race condition when accessing and creating SkCairoFTTypeface. r=rhunt

This commit is contained in:
Lee Salzman 2018-07-31 13:32:12 -04:00
parent 410bea1552
commit 0a080bf168

View File

@ -13,6 +13,7 @@
#include "SkAdvancedTypefaceMetrics.h"
#include "SkFDot6.h"
#include "SkMutex.h"
#include "SkPath.h"
#include "SkScalerContext.h"
#include "SkTypefaceCache.h"
@ -169,6 +170,8 @@ static bool isAxisAligned(const SkScalerContextRec& rec) {
bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
}
SK_DECLARE_STATIC_MUTEX(gTypefaceMutex);
class SkCairoFTTypeface : public SkTypeface {
public:
virtual SkStreamAsset* onOpenStream(int*) const override { return nullptr; }
@ -269,9 +272,19 @@ public:
}
private:
void internal_dispose() const override
{
SkAutoMutexAcquire lock(gTypefaceMutex);
internal_dispose_restore_refcnt_to_1();
delete this;
}
~SkCairoFTTypeface()
{
cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, nullptr, nullptr);
if (cairo_font_face_get_user_data(fFontFace, &kSkTypefaceKey) == this) {
cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, nullptr, nullptr);
}
cairo_font_face_destroy(fFontFace);
#ifdef CAIRO_HAS_FC_FONT
if (fPattern) {
@ -290,12 +303,13 @@ SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* s
SkASSERT(cairo_font_face_status(fontFace) == CAIRO_STATUS_SUCCESS);
SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
SkAutoMutexAcquire lock(gTypefaceMutex);
SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));
if (typeface) {
if (typeface && typeface->getRefCnt() > 0) {
typeface->ref();
} else {
typeface = new SkCairoFTTypeface(fontFace, pattern);
SkTypefaceCache::Add(typeface);
}
return typeface;