]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
Fix pango fontmap threading issue. 601/head
authorJoakim Soderberg <joakim.soderberg@gmail.com>
Wed, 1 Apr 2015 13:28:58 +0000 (15:28 +0200)
committerJoakim Soderberg <joakim.soderberg@gmail.com>
Wed, 1 Apr 2015 13:28:58 +0000 (15:28 +0200)
Since pango v1.32.6 `pango_cairo_font_map_get_default` returns a per thread `fontmap`. But since we're allocating this statically on the first call to `rrd_init`,
if we then try to access it again via another thread glib will get stuck in an infinte assertion loop.

Instead use `pango_cairo_font_map_new()` when creating the `fontmap`. This will not create a per thread version and glib will be happy.

Also added some extra locking whenever using the `im->layout` pango structure that uses the `fontmap` internally as a precaution.

src/rrd_graph.c
src/rrd_graph.h

index 168b6f27364762cefefa54f722de9b041d9db0af..7b48ad0b2139bf07b67a14fbb3b4264cf750b3ed 100644 (file)
@@ -461,9 +461,11 @@ int im_free(
         free(im->rendered_image);
     }
 
+    mutex_lock(im->fontmap_mutex);
     if (im->layout) {
         g_object_unref(im->layout);
     }
+    mutex_unlock(im->fontmap_mutex);
 
        if (im->ylegend)
                free(im->ylegend);
@@ -4656,6 +4658,7 @@ void rrd_graph_init(
     unsigned int i;
     char     *deffont = getenv("RRD_DEFAULT_FONT");
     static PangoFontMap *fontmap = NULL;
+    static mutex_t fontmap_mutex = MUTEX_INITIALIZER;
     PangoContext *context;
 
     /* zero the whole structure first */
@@ -4740,6 +4743,7 @@ void rrd_graph_init(
 
     im->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
     im->cr = cairo_create(im->surface);
+    im->fontmap_mutex = &fontmap_mutex;
 
     for (i = 0; i < DIM(text_prop); i++) {
         im->text_prop[i].size = -1;
@@ -4747,8 +4751,10 @@ void rrd_graph_init(
         rrd_set_font_desc(im,i, deffont ? deffont : text_prop[i].font,text_prop[i].size);
     }
 
+    mutex_lock(im->fontmap_mutex);
+
     if (fontmap == NULL){
-        fontmap = pango_cairo_font_map_get_default();
+        fontmap = pango_cairo_font_map_new();
     }
 
 #ifdef HAVE_PANGO_FONT_MAP_CREATE_CONTEXT
@@ -4772,7 +4778,7 @@ void rrd_graph_init(
         (im->font_options, CAIRO_HINT_METRICS_ON);
     cairo_font_options_set_antialias(im->font_options, CAIRO_ANTIALIAS_GRAY);
 
-
+    mutex_unlock(im->fontmap_mutex);
 
     for (i = 0; i < DIM(graph_col); i++)
         im->graph_col[i] = graph_col[i];
@@ -5369,8 +5375,10 @@ void rrd_graph_options(
         }
     } /* while (1) */
 
+    mutex_lock(im->fontmap_mutex);
     pango_cairo_context_set_font_options(pango_layout_get_context(im->layout), im->font_options);
     pango_layout_context_changed(im->layout);
+    mutex_unlock(im->fontmap_mutex);
 
 
     if (im->primary_axis_format != NULL && im->primary_axis_format[0] != '\0') {
index a8e03550fe8b33b9be595b7c20f3a289d36959e7..4e2019bd6b80385c73cd0d181993d15f638584d2 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
+#include "mutex.h"
 
 #include <glib.h>
 
@@ -351,6 +352,7 @@ typedef struct image_desc_t {
     rrd_info_t *grinfo_current; /* pointing to current entry */
     GHashTable* gdef_map;  /* a map of all *def gdef entries for quick access */
     GHashTable* rrd_map;  /* a map of all rrd files in use for gdef entries */
+    mutex_t *fontmap_mutex; /* Mutex for locking the global fontmap */
 } image_desc_t;
 
 /* Prototypes */