From 9ee3896017591b3fc4e85506b9979ebe6be9a049 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 22 Nov 2005 15:34:09 +0000 Subject: [PATCH] Avoid double locking in g_intern_string (#322133, Benedikt Meurer) 2005-11-22 Matthias Clasen Avoid double locking in g_intern_string (#322133, Benedikt Meurer) * glib/gdataset.c (g_quark_from_string_internal): New internal function which factors out common parts of g_quark_from[_static]_string. (g_quark_from_string, g_quark_from_static_string): Use g_quark_from_string_internal. (g_intern_string, g_intern_static_string): Use g_quark_from_string_internal, and only take the lock once. (g_quark_new): Don't store the strings shifted by -1 in the g_quarks array. (g_quark_to_string): Adapt to the previous change. --- ChangeLog | 17 +++++++++++ ChangeLog.pre-2-10 | 17 +++++++++++ ChangeLog.pre-2-12 | 17 +++++++++++ glib/gdataset.c | 76 +++++++++++++++++++++++++++++++--------------- 4 files changed, 102 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c46313c..2b695106 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-11-22 Matthias Clasen + + Avoid double locking in g_intern_string (#322133, + Benedikt Meurer) + + * glib/gdataset.c (g_quark_from_string_internal): New + internal function which factors out common parts of + g_quark_from[_static]_string. + (g_quark_from_string, g_quark_from_static_string): + Use g_quark_from_string_internal. + (g_intern_string, g_intern_static_string): Use + g_quark_from_string_internal, and only take the + lock once. + (g_quark_new): Don't store the strings shifted by -1 + in the g_quarks array. + (g_quark_to_string): Adapt to the previous change. + Tue Nov 22 14:04:26 2005 Tim Janik * glib/ghash.h: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9c46313c..2b695106 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,20 @@ +2005-11-22 Matthias Clasen + + Avoid double locking in g_intern_string (#322133, + Benedikt Meurer) + + * glib/gdataset.c (g_quark_from_string_internal): New + internal function which factors out common parts of + g_quark_from[_static]_string. + (g_quark_from_string, g_quark_from_static_string): + Use g_quark_from_string_internal. + (g_intern_string, g_intern_static_string): Use + g_quark_from_string_internal, and only take the + lock once. + (g_quark_new): Don't store the strings shifted by -1 + in the g_quarks array. + (g_quark_to_string): Adapt to the previous change. + Tue Nov 22 14:04:26 2005 Tim Janik * glib/ghash.h: diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 9c46313c..2b695106 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,20 @@ +2005-11-22 Matthias Clasen + + Avoid double locking in g_intern_string (#322133, + Benedikt Meurer) + + * glib/gdataset.c (g_quark_from_string_internal): New + internal function which factors out common parts of + g_quark_from[_static]_string. + (g_quark_from_string, g_quark_from_static_string): + Use g_quark_from_string_internal. + (g_intern_string, g_intern_static_string): Use + g_quark_from_string_internal, and only take the + lock once. + (g_quark_new): Don't store the strings shifted by -1 + in the g_quarks array. + (g_quark_to_string): Adapt to the previous change. + Tue Nov 22 14:04:26 2005 Tim Janik * glib/ghash.h: diff --git a/glib/gdataset.c b/glib/gdataset.c index f0c46bc0..7598342e 100644 --- a/glib/gdataset.c +++ b/glib/gdataset.c @@ -622,6 +622,22 @@ g_quark_try_string (const gchar *string) return quark; } +/* HOLDS: g_quark_global_lock */ +static inline GQuark +g_quark_from_string_internal (const gchar *string, + gboolean duplicate) +{ + GQuark quark = 0; + + if (g_quark_ht) + quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string)); + + if (!quark) + quark = g_quark_new (duplicate ? g_strdup (string) : (gchar *)string); + + return quark; +} + GQuark g_quark_from_string (const gchar *string) { @@ -630,16 +646,7 @@ g_quark_from_string (const gchar *string) g_return_val_if_fail (string != NULL, 0); G_LOCK (g_quark_global); - if (g_quark_ht) - quark = (gulong) g_hash_table_lookup (g_quark_ht, string); - else - { - g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal); - quark = 0; - } - - if (!quark) - quark = g_quark_new (g_strdup (string)); + quark = g_quark_from_string_internal (string, TRUE); G_UNLOCK (g_quark_global); return quark; @@ -653,18 +660,9 @@ g_quark_from_static_string (const gchar *string) g_return_val_if_fail (string != NULL, 0); G_LOCK (g_quark_global); - if (g_quark_ht) - quark = (gulong) g_hash_table_lookup (g_quark_ht, string); - else - { - g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal); - quark = 0; - } - - if (!quark) - quark = g_quark_new ((gchar*) string); + quark = g_quark_from_string_internal (string, FALSE); G_UNLOCK (g_quark_global); - + return quark; } @@ -672,9 +670,10 @@ G_CONST_RETURN gchar* g_quark_to_string (GQuark quark) { gchar* result = NULL; + G_LOCK (g_quark_global); if (quark > 0 && quark <= g_quark_seq_id) - result = g_quarks[quark - 1]; + result = g_quarks[quark]; G_UNLOCK (g_quark_global); return result; @@ -689,9 +688,14 @@ g_quark_new (gchar *string) if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0) g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE); - g_quarks[g_quark_seq_id] = string; + g_quarks[0] = NULL; g_quark_seq_id++; + g_quarks[g_quark_seq_id] = string; quark = g_quark_seq_id; + + if (!g_quark_ht) + g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark)); return quark; @@ -711,7 +715,18 @@ g_quark_new (gchar *string) G_CONST_RETURN gchar* g_intern_string (const gchar *string) { - return string ? g_quark_to_string (g_quark_from_string (string)) : NULL; + const gchar *result; + GQuark quark; + + if (!string) + return NULL; + + G_LOCK (g_quark_global); + quark = g_quark_from_string_internal (string, TRUE); + result = g_quarks[quark]; + G_UNLOCK (g_quark_global); + + return result; } /** @@ -730,7 +745,18 @@ g_intern_string (const gchar *string) G_CONST_RETURN gchar* g_intern_static_string (const gchar *string) { - return string ? g_quark_to_string (g_quark_from_static_string (string)) : NULL; + GQuark quark; + const gchar *result; + + if (!string) + return NULL; + + G_LOCK (g_quark_global); + quark = g_quark_from_string_internal (string, FALSE); + result = g_quarks[quark]; + G_UNLOCK (g_quark_global); + + return result; } -- 2.34.1