genviron: Message if g_setenv()/g_unsetenv() are used after threads spawned

g_setenv() and g_unsetenv() can never be thread-safe, so emit a message if
they are used after any threads have been spawned.

This can’t catch interactions between setenv() and g_thread_new(), or
between g_setenv() and pthread_create(), but it’ll catch most
misbehaviour in GLib-centric code.

Currently, the message is a `g_debug()` call. Eventually, I’d like to
upgrade it to a `g_warning()`, but there are a number of GLib tests
which call g_setenv() after threads have been created, and they need to
be fixed first. Emitting a `g_debug()` message gives people an
opportunity to start fixing their code.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Helps: #715
This commit is contained in:
Philip Withnall 2019-07-25 15:13:17 +01:00
parent 6271b5eb93
commit 120e6435c7

View File

@ -42,6 +42,7 @@
#include "gunicode.h"
#include "gconvert.h"
#include "gquark.h"
#include "gthreadprivate.h"
/* Environ array functions {{{1 */
static gboolean
@ -299,6 +300,13 @@ g_setenv (const gchar *variable,
g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE);
#ifndef G_DISABLE_CHECKS
/* FIXME: This will be upgraded to a g_warning() in a future release of GLib.
* See https://gitlab.gnome.org/GNOME/glib/issues/715 */
if (g_thread_n_created () > 0)
g_debug ("setenv()/putenv() are not thread-safe and should not be used after threads are created");
#endif
#ifdef HAVE_SETENV
result = setenv (variable, value, overwrite);
#else
@ -355,6 +363,13 @@ g_unsetenv (const gchar *variable)
g_return_if_fail (variable != NULL);
g_return_if_fail (strchr (variable, '=') == NULL);
#ifndef G_DISABLE_CHECKS
/* FIXME: This will be upgraded to a g_warning() in a future release of GLib.
* See https://gitlab.gnome.org/GNOME/glib/issues/715 */
if (g_thread_n_created () > 0)
g_debug ("unsetenv() is not thread-safe and should not be used after threads are created");
#endif
#ifdef HAVE_UNSETENV
unsetenv (variable);
#else /* !HAVE_UNSETENV */