From: Matthias Clasen Date: Fri, 15 Dec 2006 04:35:13 +0000 (+0000) Subject: Don't use alloca and avoid allocating memory for small keys that are X-Git-Tag: GLIB_2_13_0~186 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0fffe4abc42c5eda8e5af192b9f65eb0a5ab656d;p=platform%2Fupstream%2Fglib.git Don't use alloca and avoid allocating memory for small keys that are 2006-12-14 Matthias Clasen * glib/gconvert.c (open_converter): Don't use alloca and avoid allocating memory for small keys that are already cached. (#172406, Morten Welinder) --- diff --git a/ChangeLog b/ChangeLog index 5525b97..f691dc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2006-12-14 Matthias Clasen + * glib/gconvert.c (open_converter): Don't use alloca + and avoid allocating memory for small keys that are + already cached. (#172406, Morten Welinder) + * glib/gmain.c (g_child_watch_add_full): Improve the docs. (#345569, Tim-Philipp Müller) diff --git a/glib/gconvert.c b/glib/gconvert.c index c5e4f50..e5b476b 100644 --- a/glib/gconvert.c +++ b/glib/gconvert.c @@ -2,7 +2,7 @@ * * gconvert.c: Convert between character sets using iconv * Copyright Red Hat Inc., 2000 - * Authors: Havoc Pennington , Owen Taylor , Owen Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -235,15 +235,17 @@ iconv_cache_init (void) * Creates a new cache bucket, inserts it into the cache and * increments the cache size. * + * This assumes ownership of @key. + * * Returns a pointer to the newly allocated cache bucket. **/ static struct _iconv_cache_bucket * -iconv_cache_bucket_new (const gchar *key, GIConv cd) +iconv_cache_bucket_new (gchar *key, GIConv cd) { struct _iconv_cache_bucket *bucket; bucket = g_new (struct _iconv_cache_bucket, 1); - bucket->key = g_strdup (key); + bucket->key = key; bucket->refcount = 1; bucket->used = TRUE; bucket->cd = cd; @@ -336,13 +338,24 @@ open_converter (const gchar *to_codeset, GError **error) { struct _iconv_cache_bucket *bucket; - gchar *key; + gchar *key, *dyn_key, auto_key[80]; GIConv cd; + gsize len_from_codeset, len_to_codeset; /* create our key */ - key = g_alloca (strlen (from_codeset) + strlen (to_codeset) + 2); - _g_sprintf (key, "%s:%s", from_codeset, to_codeset); - + len_from_codeset = strlen (from_codeset); + len_to_codeset = strlen (to_codeset); + if (len_from_codeset + len_to_codeset + 2 < sizeof (auto_key)) + { + key = auto_key; + dyn_key = NULL; + } + else + key = dyn_key = g_malloc (len_from_codeset + len_to_codeset + 2); + memcpy (key, from_codeset, len_from_codeset); + key[len_from_codeset] = ':'; + strcpy (key + len_from_codeset + 1, to_codeset); + G_LOCK (iconv_cache_lock); /* make sure the cache has been initialized */ @@ -351,6 +364,8 @@ open_converter (const gchar *to_codeset, bucket = g_hash_table_lookup (iconv_cache, key); if (bucket) { + g_free (dyn_key); + if (bucket->used) { cd = g_iconv_open (to_codeset, from_codeset); @@ -379,12 +394,15 @@ open_converter (const gchar *to_codeset, else { cd = g_iconv_open (to_codeset, from_codeset); - if (cd == (GIConv) -1) - goto error; + if (cd == (GIConv) -1) + { + g_free (dyn_key); + goto error; + } iconv_cache_expire_unused (); - - bucket = iconv_cache_bucket_new (key, cd); + + bucket = iconv_cache_bucket_new (dyn_key ? dyn_key : g_strdup (key), cd); } g_hash_table_insert (iconv_open_hash, cd, bucket->key);