From 96675446c5fc9b47265124e479cc300f7a7ced65 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 6 Aug 2015 15:39:22 -0400 Subject: [PATCH] Make g_strerror() do less work Store the (translated, UTF-8-encoded) error strings in a hash table to avoid doing translation and (possibly) g_locale_to_utf8() in every g_strerror() call. https://bugzilla.gnome.org/show_bug.cgi?id=754788 --- glib/gstrfuncs.c | 55 ++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index 7d6e8ef86..dde612668 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -1253,40 +1253,53 @@ g_ascii_strtoll (const gchar *nptr, const gchar * g_strerror (gint errnum) { - gchar buf[1024]; - gchar *msg; - gchar *tofree = NULL; - const gchar *ret; + static GHashTable *errors; + G_LOCK_DEFINE_STATIC (errors); + const gchar *msg; gint saved_errno = errno; - GError *error = NULL; + + G_LOCK (errors); + if (errors) + msg = g_hash_table_lookup (errors, GINT_TO_POINTER (errnum)); + else + { + errors = g_hash_table_new (NULL, NULL); + msg = NULL; + } + + if (!msg) + { + gchar buf[1024]; + GError *error = NULL; #if defined(G_OS_WIN32) - strerror_s (buf, sizeof (buf), errnum); - msg = buf; + strerror_s (buf, sizeof (buf), errnum); + msg = buf; #elif defined(HAVE_STRERROR_R) /* Match the condition in strerror_r(3) for glibc */ # if defined(__GLIBC__) && !((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE) - msg = strerror_r (errnum, buf, sizeof (buf)); + msg = strerror_r (errnum, buf, sizeof (buf)); # else - strerror_r (errnum, buf, sizeof (buf)); - msg = buf; + strerror_r (errnum, buf, sizeof (buf)); + msg = buf; # endif /* HAVE_STRERROR_R */ #else - g_strlcpy (buf, strerror (errnum), sizeof (buf)); - msg = buf; + g_strlcpy (buf, strerror (errnum), sizeof (buf)); + msg = buf; #endif - if (!g_get_charset (NULL)) - { - msg = tofree = g_locale_to_utf8 (msg, -1, NULL, NULL, &error); - if (error) - g_print ("%s\n", error->message); - } + if (!g_get_charset (NULL)) + { + msg = g_locale_to_utf8 (msg, -1, NULL, NULL, &error); + if (error) + g_print ("%s\n", error->message); + } - ret = g_intern_string (msg); - g_free (tofree); + g_hash_table_insert (errors, GINT_TO_POINTER (errnum), (char *) msg); + } + G_UNLOCK (errors); errno = saved_errno; - return ret; + return msg; } /**