[glib] Only g_system_thread_free() our own threads



commit dfd466979be8ab93d7c569c3e5199a02d03671e8
Author: Ryan Lortie <desrt desrt ca>
Date:   Wed Oct 12 23:16:49 2011 -0400

    Only g_system_thread_free() our own threads
    
    Keep track of if we created a thread for ourselves or if the GThread*
    was allocated in response to g_thread_self() on a previously-unknown
    thread.
    
    Only call g_system_thread_free() in the first case.

 glib/gthread.c        |   21 +++++++++++++--------
 glib/gthreadprivate.h |    2 ++
 2 files changed, 15 insertions(+), 8 deletions(-)
---
diff --git a/glib/gthread.c b/glib/gthread.c
index 7896df8..8917db1 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -677,7 +677,12 @@ g_thread_cleanup (gpointer data)
        * If it is, the structure is freed in g_thread_join()
        */
       if (!thread->thread.joinable)
-        g_system_thread_free (thread);
+        {
+          if (thread->ours)
+            g_system_thread_free (thread);
+          else
+            g_slice_free (GRealThread, thread);
+        }
     }
 }
 
@@ -807,6 +812,7 @@ g_thread_new_internal (const gchar   *name,
   thread = g_system_thread_new (proxy, stack_size, joinable, error);
   if (thread)
     {
+      thread->ours = TRUE;
       thread->thread.joinable = joinable;
       thread->thread.func = func;
       thread->thread.data = data;
@@ -886,7 +892,10 @@ g_thread_join (GThread *thread)
    * thread end. We free the memory here. This will leave a loose end,
    * if a joinable thread is not joined.
    */
-  g_system_thread_free (real);
+  if (real->ours)
+    g_system_thread_free (real);
+  else
+    g_slice_free (GRealThread, real);
 
   return retval;
 }
@@ -910,15 +919,11 @@ g_thread_self (void)
        * This can happen for the main thread and for threads
        * that are not created by GLib.
        */
-      thread = g_new0 (GRealThread, 1);
-      thread->thread.joinable = FALSE; /* This is a safe guess */
-      thread->thread.func = NULL;
-      thread->thread.data = NULL;
-
+      thread = g_slice_new0 (GRealThread);
       g_private_set (&g_thread_specific_private, thread);
     }
 
-  return (GThread*)thread;
+  return (GThread*) thread;
 }
 
 /* Epilogue {{{1 */
diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h
index de847e4..725da4b 100644
--- a/glib/gthreadprivate.h
+++ b/glib/gthreadprivate.h
@@ -59,6 +59,8 @@ gpointer        g_thread_proxy                  (gpointer     thread);
 struct  _GRealThread
 {
   GThread thread;
+
+  gboolean ours;
   const gchar *name;
   gpointer retval;
 };



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