diff options
author | Philip Withnall <pwithnall@endlessos.org> | 2020-09-30 16:16:11 +0100 |
---|---|---|
committer | Christian Hergert <chergert@redhat.com> | 2020-12-17 10:30:54 -0800 |
commit | e4af46fc09b99c606a5c2a0af511e0352ff1b4be (patch) | |
tree | 075b40ed277b02034bfc385588ac6f5e16c359c6 | |
parent | bacbec652d356895ec493f3de2f2f6f4c7dafde0 (diff) | |
download | glib-wip/chergert/merge-private-fix.tar.gz |
gthread: Destroy value after replacing it in g_private_replace()wip/chergert/merge-private-fix
If the old value is destroyed before updating the TLS value in pthreads
(or the Windows equivalent) then there’s a risk of infinite recursion if
`g_private_replace()` is called from within the `GDestroyNotify`.
Avoid that by destroying the old value after doing the TLS update.
Thanks to Matthias Clasen for diagnosing the issue.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2210
-rw-r--r-- | glib/gthread-posix.c | 5 | ||||
-rw-r--r-- | glib/gthread-win32.c | 2 |
2 files changed, 4 insertions, 3 deletions
diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c index f36055925..f09f58a15 100644 --- a/glib/gthread-posix.c +++ b/glib/gthread-posix.c @@ -1116,11 +1116,12 @@ g_private_replace (GPrivate *key, gint status; old = pthread_getspecific (*impl); - if (old && key->notify) - key->notify (old); if G_UNLIKELY ((status = pthread_setspecific (*impl, value)) != 0) g_thread_abort (status, "pthread_setspecific"); + + if (old && key->notify) + key->notify (old); } /* {{{1 GThread */ diff --git a/glib/gthread-win32.c b/glib/gthread-win32.c index 54f74f2f8..0c37dc6c1 100644 --- a/glib/gthread-win32.c +++ b/glib/gthread-win32.c @@ -373,9 +373,9 @@ g_private_replace (GPrivate *key, gpointer old; old = TlsGetValue (impl); + TlsSetValue (impl, value); if (old && key->notify) key->notify (old); - TlsSetValue (impl, value); } /* {{{1 GThread */ |