diff --git a/configure.ac b/configure.ac
index 47331cf..0277ca5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -958,6 +958,9 @@ AC_CHECK_FUNCS(splice)
 AC_CHECK_HEADERS(crt_externs.h)
 AC_CHECK_FUNCS(_NSGetEnviron)
 
+AC_CHECK_TYPES(locale_t)
+AC_CHECK_FUNCS(strtod_l strtoll_l strtoull_l)
+
 AC_FUNC_VSNPRINTF_C99
 AC_FUNC_PRINTF_UNIX98
 
diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c
index 04f686b..1fef74a 100644
--- a/glib/gstrfuncs.c
+++ b/glib/gstrfuncs.c
@@ -35,6 +35,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <locale.h>
 #include <string.h>
 #include <locale.h>
 #include <errno.h>
@@ -80,6 +81,27 @@ static const guint16 ascii_table_data[256] = {
 
 const guint16 * const g_ascii_table = ascii_table_data;
 
+#ifdef HAVE_LOCALE_T
+static locale_t
+get_C_locale (void)
+{
+  static locale_t C_locale = NULL;
+
+  if (G_UNLIKELY (C_locale == NULL))
+    C_locale = newlocale (LC_ALL_MASK, "C", NULL);
+
+  return C_locale;
+}
+#endif
+
+void
+_g_locale_thread_init (void)
+{
+#ifdef HAVE_LOCALE_T
+  get_C_locale ();
+#endif
+}
+
 /**
  * g_strdup:
  * @str: the string to duplicate
@@ -429,6 +451,9 @@ gdouble
 g_ascii_strtod (const gchar *nptr,
                 gchar      **endptr)
 {
+#ifdef HAVE_STRTOD_L
+  return strtod_l (nptr, endptr, get_C_locale ());
+#else
   gchar *fail_pos;
   gdouble val;
   struct lconv *locale_data;
@@ -573,6 +598,7 @@ g_ascii_strtod (const gchar *nptr,
   errno = strtod_errno;
 
   return val;
+#endif
 }
 
 
@@ -692,6 +718,16 @@ g_ascii_formatd (gchar       *buffer,
   return buffer;
 }
 
+#define ISSPACE(c)              ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
+                                 (c) == '\r' || (c) == '\t' || (c) == '\v')
+#define ISUPPER(c)              ((c) >= 'A' && (c) <= 'Z')
+#define ISLOWER(c)              ((c) >= 'a' && (c) <= 'z')
+#define ISALPHA(c)              (ISUPPER (c) || ISLOWER (c))
+#define TOUPPER(c)              (ISLOWER (c) ? (c) - 'a' + 'A' : (c))
+#define TOLOWER(c)              (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
+
+#if !defined(HAVE_STRTOLL_L) || !defined(HAVE_STRTOULL_L)
+
 static guint64
 g_parse_long_long (const gchar  *nptr,
                    const gchar **endptr,
@@ -704,13 +740,6 @@ g_parse_long_long (const gchar  *nptr,
    * Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02
    *        Free Software Foundation, Inc.
    */
-#define ISSPACE(c)              ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
-                                 (c) == '\r' || (c) == '\t' || (c) == '\v')
-#define ISUPPER(c)              ((c) >= 'A' && (c) <= 'Z')
-#define ISLOWER(c)              ((c) >= 'a' && (c) <= 'z')
-#define ISALPHA(c)              (ISUPPER (c) || ISLOWER (c))
-#define TOUPPER(c)              (ISLOWER (c) ? (c) - 'a' + 'A' : (c))
-#define TOLOWER(c)              (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
   gboolean overflow;
   guint64 cutoff;
   guint64 cutlim;
@@ -822,6 +851,7 @@ g_parse_long_long (const gchar  *nptr,
     }
   return 0;
 }
+#endif
 
 /**
  * g_ascii_strtoull:
@@ -856,6 +886,9 @@ g_ascii_strtoull (const gchar *nptr,
                   gchar      **endptr,
                   guint        base)
 {
+#ifdef HAVE_STRTOULL_L
+  return strtoull_l (nptr, endptr, base, get_C_locale());
+#else
   gboolean negative;
   guint64 result;
 
@@ -863,6 +896,7 @@ g_ascii_strtoull (const gchar *nptr,
 
   /* Return the result of the appropriate sign.  */
   return negative ? -result : result;
+#endif
 }
 
 /**
@@ -898,6 +932,9 @@ g_ascii_strtoll (const gchar *nptr,
                  gchar      **endptr,
                  guint        base)
 {
+#ifdef HAVE_STRTOLL_L
+  return strtoll_l (nptr, endptr, base, get_C_locale ());
+#else
   gboolean negative;
   guint64 result;
 
@@ -917,6 +954,7 @@ g_ascii_strtoll (const gchar *nptr,
     return - (gint64) result;
   else
     return (gint64) result;
+#endif
 }
 
 /**
diff --git a/glib/gthread.c b/glib/gthread.c
index 971aedb..2e8d3ee 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -937,6 +937,7 @@ g_thread_init_glib (void)
   _g_messages_thread_init_nomessage ();
 
   /* we may run full-fledged initializers from here */
+  _g_locale_thread_init ();
   _g_atomic_thread_init ();
   _g_convert_thread_init ();
   _g_rand_thread_init ();
diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h
index c75924c..790e611 100644
--- a/glib/gthreadprivate.h
+++ b/glib/gthreadprivate.h
@@ -53,6 +53,7 @@ G_GNUC_INTERNAL void _g_slice_thread_init_nomessage	    (void);
 G_GNUC_INTERNAL void _g_messages_thread_init_nomessage      (void);
 
 /* full fledged initializers */
+G_GNUC_INTERNAL void _g_locale_thread_init (void);
 G_GNUC_INTERNAL void _g_convert_thread_init (void);
 G_GNUC_INTERNAL void _g_rand_thread_init (void);
 G_GNUC_INTERNAL void _g_main_thread_init (void);
