Bug 1425346 - lock access to cairo_ft_unscaled_font_t's faces list. r=jrmuizel
authorLee Salzman <lsalzman@mozilla.com>
Tue, 09 Jan 2018 16:18:38 -0500
changeset 398510 fa08ddd9db32181167c5823fc20cdb2c3fb980ce
parent 398509 9812c5d6f760aa9aafeee791692f9a056335053a
child 398511 bcbf0e6ea93c4213dd44b6634ca6a79d66888e5b
push id33221
push userrgurzau@mozilla.com
push dateWed, 10 Jan 2018 09:58:44 +0000
treeherdermozilla-central@d5f42a23909e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1425346
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1425346 - lock access to cairo_ft_unscaled_font_t's faces list. r=jrmuizel MozReview-Commit-ID: GjIiO7P9Wak
gfx/cairo/cairo/src/cairo-ft-font.c
--- a/gfx/cairo/cairo/src/cairo-ft-font.c
+++ b/gfx/cairo/cairo/src/cairo-ft-font.c
@@ -2700,31 +2700,33 @@ static void
      *   font_face ------> unscaled
      *        <-....weak....../
      *
      * To:
      *
      *    font_face <------- unscaled
      */
 
-    if (font_face->unscaled &&
-	font_face->unscaled->from_face &&
-	font_face->next == NULL &&
-	font_face->unscaled->faces == font_face &&
-	CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
+    if (font_face->unscaled)
     {
-	cairo_font_face_reference (&font_face->base);
-
-	_cairo_unscaled_font_destroy (&font_face->unscaled->base);
-	font_face->unscaled = NULL;
-
-	return;
-    }
-
-    if (font_face->unscaled) {
+	CAIRO_MUTEX_LOCK (font_face->unscaled->mutex);
+
+	if (font_face->unscaled->from_face &&
+	    font_face->next == NULL &&
+	    font_face->unscaled->faces == font_face &&
+	    CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1)
+	{
+	    cairo_font_face_reference (&font_face->base);
+
+	    CAIRO_MUTEX_UNLOCK (font_face->unscaled->mutex);
+	    _cairo_unscaled_font_destroy (&font_face->unscaled->base);
+	    font_face->unscaled = NULL;
+	    return;
+	}
+
 	cairo_ft_font_face_t *tmp_face = NULL;
 	cairo_ft_font_face_t *last_face = NULL;
 
 	/* Remove face from linked list */
 	for (tmp_face = font_face->unscaled->faces;
 	     tmp_face;
 	     tmp_face = tmp_face->next)
 	{
@@ -2733,16 +2735,17 @@ static void
 		    last_face->next = tmp_face->next;
 		else
 		    font_face->unscaled->faces = tmp_face->next;
 	    }
 
 	    last_face = tmp_face;
 	}
 
+	CAIRO_MUTEX_UNLOCK (font_face->unscaled->mutex);
 	_cairo_unscaled_font_destroy (&font_face->unscaled->base);
 	font_face->unscaled = NULL;
     }
 
 #if CAIRO_HAS_FC_FONT
     if (font_face->pattern) {
 	FcPatternDestroy (font_face->pattern);
 	cairo_font_face_destroy (font_face->resolved_font_face);
@@ -2850,16 +2853,18 @@ static cairo_status_t
 #endif
 
 static cairo_font_face_t *
 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
 			    cairo_ft_options_t	     *ft_options)
 {
     cairo_ft_font_face_t *font_face, **prev_font_face;
 
+    CAIRO_MUTEX_LOCK (unscaled->mutex);
+
     /* Looked for an existing matching font face */
     for (font_face = unscaled->faces, prev_font_face = &unscaled->faces;
 	 font_face;
 	 prev_font_face = &font_face->next, font_face = font_face->next)
     {
 	if (font_face->ft_options.load_flags == ft_options->load_flags &&
 	    font_face->ft_options.extra_flags == ft_options->extra_flags &&
 	    cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base))
@@ -2871,25 +2876,29 @@ static cairo_font_face_t *
 	    }
 
 	    if (font_face->unscaled == NULL) {
 		/* Resurrect this "zombie" font_face (from
 		 * _cairo_ft_font_face_destroy), switching its unscaled_font
 		 * from owner to ownee. */
 		font_face->unscaled = unscaled;
 		_cairo_unscaled_font_reference (&unscaled->base);
-		return &font_face->base;
-	    } else
-		return cairo_font_face_reference (&font_face->base);
+	    } else {
+		cairo_font_face_reference (&font_face->base);
+	    }
+
+	    CAIRO_MUTEX_UNLOCK (unscaled->mutex);
+	    return &font_face->base;
 	}
     }
 
     /* No match found, create a new one */
     font_face = malloc (sizeof (cairo_ft_font_face_t));
     if (unlikely (!font_face)) {
+	CAIRO_MUTEX_UNLOCK (unscaled->mutex);
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
     }
 
     font_face->unscaled = unscaled;
     _cairo_unscaled_font_reference (&unscaled->base);
 
     font_face->ft_options = *ft_options;
@@ -2906,16 +2915,17 @@ static cairo_font_face_t *
     unscaled->faces = font_face;
 
 #if CAIRO_HAS_FC_FONT
     font_face->pattern = NULL;
 #endif
 
     _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
 
+    CAIRO_MUTEX_UNLOCK (unscaled->mutex);
     return &font_face->base;
 }
 
 /* implement the platform-specific interface */
 
 #if CAIRO_HAS_FC_FONT
 static cairo_status_t
 _cairo_ft_font_options_substitute (const cairo_font_options_t *options,