[glib/wip/chergert/merge-private-fix] gthread: Destroy value after replacing it in g_private_replace()




commit e4af46fc09b99c606a5c2a0af511e0352ff1b4be
Author: Philip Withnall <pwithnall endlessos org>
Date:   Wed Sep 30 16:16:11 2020 +0100

    gthread: Destroy value after replacing it in g_private_replace()
    
    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

 glib/gthread-posix.c | 5 +++--
 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 */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]