+2005-11-22 Matthias Clasen <mclasen@redhat.com>
+
+ 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 <timj@imendio.com>
* glib/ghash.h:
+2005-11-22 Matthias Clasen <mclasen@redhat.com>
+
+ 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 <timj@imendio.com>
* glib/ghash.h:
+2005-11-22 Matthias Clasen <mclasen@redhat.com>
+
+ 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 <timj@imendio.com>
* glib/ghash.h:
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)
{
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;
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;
}
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;
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;
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;
}
/**
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;
}