From adfdc21527c4bd31cb350d08c26fce654f0220d3 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Mon, 30 Jul 2018 12:11:46 -0400 Subject: [PATCH] Bug 1473732 - Avoid race condition when accessing and creating SkCairoFTTypeface. r=rhunt --HG-- extra : rebase_source : 658a1fc2a7e3f3bcab1c6f5d7a5070d762beaeef --- gfx/skia/skia/src/ports/SkFontHost_cairo.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp b/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp index 9869569fa6a8..fcc2ae6e6a78 100644 --- a/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_cairo.cpp @@ -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(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;