summaryrefslogtreecommitdiff
path: root/recipes/glib/0001-gslice-Inline-win32-implementation-of-g_getenv-to-av.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/glib/0001-gslice-Inline-win32-implementation-of-g_getenv-to-av.patch')
-rw-r--r--recipes/glib/0001-gslice-Inline-win32-implementation-of-g_getenv-to-av.patch89
1 files changed, 89 insertions, 0 deletions
diff --git a/recipes/glib/0001-gslice-Inline-win32-implementation-of-g_getenv-to-av.patch b/recipes/glib/0001-gslice-Inline-win32-implementation-of-g_getenv-to-av.patch
new file mode 100644
index 00000000..c4920a87
--- /dev/null
+++ b/recipes/glib/0001-gslice-Inline-win32-implementation-of-g_getenv-to-av.patch
@@ -0,0 +1,89 @@
+From b538cb0c8c829ba76d4a04be0c198e5d3b7c311c Mon Sep 17 00:00:00 2001
+From: Philip Withnall <pwithnall@endlessos.org>
+Date: Thu, 15 Oct 2020 10:20:10 +0100
+Subject: [PATCH] gslice: Inline win32 implementation of g_getenv() to avoid
+ deadlock
+
+The win32 implementation of `g_getenv()` uses GSlice (from within
+GQuark), which results in a deadlock when examining the `G_SLICE`
+environment variable.
+
+Fix that by inlining a basic implementation of `g_getenv()` at that call
+site.
+
+Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
+
+Fixes: #2225
+---
+ glib/gslice.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/glib/gslice.c b/glib/gslice.c
+index e6f278539..589619080 100644
+--- a/glib/gslice.c
++++ b/glib/gslice.c
+@@ -361,10 +361,52 @@ static void
+ slice_config_init (SliceConfig *config)
+ {
+ const gchar *val;
++ gchar *val_allocated = NULL;
+
+ *config = slice_config;
+
++ /* Note that the empty string (`G_SLICE=""`) is treated differently from the
++ * envvar being unset. In the latter case, we also check whether running under
++ * valgrind. */
++#ifndef G_OS_WIN32
+ val = g_getenv ("G_SLICE");
++#else
++ /* The win32 implementation of g_getenv() has to do UTF-8 ↔ UTF-16 conversions
++ * which use the slice allocator, leading to deadlock. Use a simple in-place
++ * implementation here instead.
++ *
++ * Ignore references to other environment variables: only support values which
++ * are a combination of always-malloc and debug-blocks. */
++ {
++
++ wchar_t wvalue[128]; /* at least big enough for `always-malloc,debug-blocks` */
++ int len;
++
++ len = GetEnvironmentVariableW (L"G_SLICE", wvalue, G_N_ELEMENTS (wvalue));
++
++ if (len == 0)
++ {
++ if (GetLastError () == ERROR_ENVVAR_NOT_FOUND)
++ val = NULL;
++ else
++ val = "";
++ }
++ else if (len >= G_N_ELEMENTS (wvalue))
++ {
++ /* @wvalue isn’t big enough. Give up. */
++ g_warning ("Unsupported G_SLICE value");
++ val = NULL;
++ }
++ else
++ {
++ /* it’s safe to use g_utf16_to_utf8() here as it only allocates using
++ * malloc() rather than GSlice */
++ val = val_allocated = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL);
++ }
++
++ }
++#endif /* G_OS_WIN32 */
++
+ if (val != NULL)
+ {
+ gint flags;
+@@ -392,6 +434,8 @@ slice_config_init (SliceConfig *config)
+ config->always_malloc = TRUE;
+ #endif
+ }
++
++ g_free (val_allocated);
+ }
+
+ static void
+--
+2.25.1
+