summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-08-19 21:48:34 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-08-19 21:48:34 (GMT)
commit7f973e015eb59b626edc584a19a1ad3ffddf4867 (patch)
treeb55a797927df5b4feafb42c722f4583f0593cf74
parentdd9974a5c2770a066d8b4edf47b41034fbd41c72 (diff)
Fixed some concurrency issues with segment reference counters.
-rw-r--r--src/glibext/linesegment.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/src/glibext/linesegment.c b/src/glibext/linesegment.c
index 15fde78..bd11afc 100644
--- a/src/glibext/linesegment.c
+++ b/src/glibext/linesegment.c
@@ -111,7 +111,7 @@ static segment_rendering _seg_params;
/* Fragment de caractères aux propriétés potentiellement partagées */
struct _line_segment
{
- unsigned int ref_count; /* Compteur de références */
+ gint ref_count; /* Compteur de références */
rendering_pattern_t *pattern; /* Propriétés du rendu */
@@ -123,6 +123,7 @@ struct _line_segment
/* Conservation de toutes les créations partagées */
static GHashTable *_segcnt_htable;
+G_LOCK_DEFINE_STATIC(_segcnt_mutex);
/* Fournit l'empreinte d'un contenu pour segments. */
@@ -309,9 +310,11 @@ static bool is_line_segment_equal(const line_segment *content, const line_segmen
result = (content->pattern == other->pattern);
- result &= (cmp_fnv_64a(content->hash, other->hash) == 0);
+ if (result)
+ result = (cmp_fnv_64a(content->hash, other->hash) == 0);
- result &= (strcmp(content->text, other->text) == 0);
+ if (result)
+ result = (strcmp(content->text, other->text) == 0);
return result;
@@ -340,10 +343,7 @@ static line_segment *get_shared_segment_content(const line_segment *content)
gboolean created; /* Validation de mise en place */
#endif
- /**
- * On considère qu'il n'y a pas besoin de mutex ici, puisque toutes les
- * opérations se réalisent à priori dans le seul thread principal pour l'affichage.
- */
+ G_LOCK(_segcnt_mutex);
found = g_hash_table_lookup_extended(_segcnt_htable, content, (gpointer *)&result, NULL);
@@ -355,7 +355,7 @@ static line_segment *get_shared_segment_content(const line_segment *content)
memcpy(result, content, allocated);
- result->ref_count = 1;
+ g_atomic_int_set(&result->ref_count, 1);
#ifndef NDEBUG
created = g_hash_table_insert(_segcnt_htable, result, result);
@@ -370,10 +370,12 @@ static line_segment *get_shared_segment_content(const line_segment *content)
{
assert(result->ref_count < UINT_MAX);
- result->ref_count++;
+ g_atomic_int_inc(&result->ref_count);
}
+ G_UNLOCK(_segcnt_mutex);
+
return result;
}
@@ -397,19 +399,19 @@ static void release_shared_segment_content(line_segment *content)
gboolean deleted; /* Validation de suppression */
#endif
- /**
- * On considère qu'il n'y a pas besoin de mutex ici, puisque toutes les
- * opérations se réalisent à priori dans le seul thread principal pour l'affichage.
- */
-
- if (--content->ref_count == 0)
+ if (g_atomic_int_dec_and_test(&content->ref_count))
{
+ G_LOCK(_segcnt_mutex);
+
#ifndef NDEBUG
deleted = g_hash_table_remove(_segcnt_htable, content);
assert(deleted);
#else
g_hash_table_remove(_segcnt_htable, content);
#endif
+
+ G_UNLOCK(_segcnt_mutex);
+
}
}
@@ -480,7 +482,7 @@ line_segment *get_new_line_segment(RenderingTagType type, const char *text, size
void ref_line_segment(line_segment *segment)
{
- segment->ref_count++;
+ g_atomic_int_inc(&segment->ref_count);
}