Moved func and arg members from GRealThread to GThread, such that they can
authorSebastian Wilhelmi <wilhelmi@ira.uka.de>
Tue, 8 May 2001 08:23:18 +0000 (08:23 +0000)
committerSebastian Wilhelmi <wilhelmi@src.gnome.org>
Tue, 8 May 2001 08:23:18 +0000 (08:23 +0000)
2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>

* gmain.c, gthread.c, gthread.h: Moved func and arg members from
GRealThread to GThread, such that they can be accessed by the
user.

* gthread.c, gthread.h: Due to popular demand (Tim being the
populus here ;-) threads now have a 'return value', which is
returned by g_thread_join and is either the return of the topmost
thread function or the value given to g_thread_exit.

* gthreadpool.c, tests/mainloop-test.c, tests/thread-test.c:
Adapted to the above change.

18 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib/gmain.c
glib/gthread.c
glib/gthread.h
glib/gthreadpool.c
gmain.c
gthread.c
gthread.h
gthreadpool.c
tests/mainloop-test.c
tests/thread-test.c

index 37ab692..848460d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 37ab692..848460d 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 37ab692..848460d 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 37ab692..848460d 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 37ab692..848460d 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 37ab692..848460d 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 37ab692..848460d 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 37ab692..848460d 100644 (file)
@@ -1,3 +1,17 @@
+2001-05-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gmain.c, gthread.c, gthread.h: Moved func and arg members from
+       GRealThread to GThread, such that they can be accessed by the
+       user.
+
+       * gthread.c, gthread.h: Due to popular demand (Tim being the
+       populus here ;-) threads now have a 'return value', which is
+       returned by g_thread_join and is either the return of the topmost
+       thread function or the value given to g_thread_exit.
+       
+       * gthreadpool.c, tests/mainloop-test.c, test/thread-test.c:
+       Adapted to the above change.
+
 2001-01-06  Hans Breuer  <hans@breuer.org>
 
        * glib.def : don't try to export g_strcpy, it is g_stpcpy;
index 1fa20fe..10905a2 100644 (file)
@@ -544,9 +544,6 @@ typedef struct _GRealThread GRealThread;
 struct  _GRealThread
 {
   GThread thread;
-  GThreadFunc func;
-  gpointer arg;
-  gpointer private_data;
   GMainContext *context;
 };
 
index 8ee0c99..e3b8a5b 100644 (file)
@@ -74,10 +74,9 @@ typedef struct _GRealThread GRealThread;
 struct  _GRealThread
 {
   GThread thread;
-  GThreadFunc func;
-  gpointer arg;
-  gpointer private_data;
   GMainContext *context;
+  gpointer private_data;
+  gpointer retval;
   GSystemThread system_thread;
 #ifdef G_THREAD_USE_PID_SURROGATE
   pid_t pid;
@@ -512,7 +511,7 @@ g_thread_fail (void)
   g_error ("The thread system is not yet initialized.");
 }
 
-static void 
+static gpointer
 g_thread_create_proxy (gpointer data)
 {
   GRealThread* thread = data;
@@ -527,7 +526,7 @@ g_thread_create_proxy (gpointer data)
   g_private_set (g_thread_specific_private, data);
 
   /* the lock makes sure, that thread->system_thread is written,
-     before thread->func is called. See g_thread_create. */
+     before thread->thread.func is called. See g_thread_create. */
   G_LOCK (g_thread);
   G_UNLOCK (g_thread);
  
@@ -536,7 +535,9 @@ g_thread_create_proxy (gpointer data)
     SET_PRIO (thread->pid, thread->thread.priority);
 #endif /* G_THREAD_USE_PID_SURROGATE */
 
-  thread->func (thread->arg);
+  thread->retval = thread->thread.func (thread->thread.arg);
+
+  return NULL;
 }
 
 GThread* 
@@ -557,8 +558,8 @@ g_thread_create (GThreadFunc                 thread_func,
   result->thread.joinable = joinable;
   result->thread.bound = bound;
   result->thread.priority = priority;
-  result->func = thread_func;
-  result->arg = arg;
+  result->thread.func = thread_func;
+  result->thread.arg = arg;
   result->private_data = NULL; 
   result->context = NULL;
   G_LOCK (g_thread);
@@ -578,18 +579,29 @@ g_thread_create (GThreadFunc               thread_func,
   return (GThread*) result;
 }
 
-void 
+void
+g_thread_exit (gpointer retval)
+{
+  GRealThread* real = (GRealThread*) g_thread_self ();
+  real->retval = retval;
+  G_THREAD_CF (thread_exit, (void)0, ());
+}
+
+gpointer
 g_thread_join (GThread* thread)
 {
   GRealThread* real = (GRealThread*) thread;
-  
+  gpointer retval;
 
-  g_return_if_fail (thread);
-  g_return_if_fail (thread->joinable);
-  g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
+  g_return_val_if_fail (thread, NULL);
+  g_return_val_if_fail (thread->joinable, NULL);
+  g_return_val_if_fail (!g_system_thread_equal (real->system_thread, 
+                                               zero_thread), NULL);
 
   G_THREAD_UF (thread_join, (&real->system_thread));
 
+  retval = real->retval;
+
   G_LOCK (g_thread);
   g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
   G_UNLOCK (g_thread);
@@ -599,10 +611,12 @@ g_thread_join (GThread* thread)
   g_system_thread_assign (real->system_thread, zero_thread);
 
   /* the thread structure for non-joinable threads is freed upon
-     thread end. We free the memory here. This will leave loose end,
+     thread end. We free the memory here. This will leave loose end,
      if a joinable thread is not joined. */
 
   g_free (thread);
+
+  return retval;
 }
 
 void
@@ -642,8 +656,8 @@ g_thread_self (void)
       thread->thread.bound = TRUE; /* This isn't important at all */
       thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
                                                             just a guess */
-      thread->func = NULL;
-      thread->arg = NULL;
+      thread->thread.func = NULL;
+      thread->thread.arg = NULL;
       thread->private_data = NULL;
       thread->context = NULL;
 
index 2f147b4..6a1bfba 100644 (file)
@@ -43,7 +43,7 @@ typedef enum
   G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */
 } GThreadError;
 
-typedef void            (*GThreadFunc)          (gpointer       value);
+typedef gpointer (*GThreadFunc) (gpointer value);
 
 typedef enum
 {
@@ -59,6 +59,8 @@ struct  _GThread
   gboolean joinable;
   gboolean bound;
   GThreadPriority priority;
+  GThreadFunc func;
+  gpointer arg;
 };
 
 typedef struct _GMutex          GMutex;
@@ -191,19 +193,20 @@ GMutex* g_static_mutex_get_mutex_impl   (GMutex **mutex);
                                                         (GPrivate*) (value)), \
                                                        (private_key, value))
 #define g_thread_yield()              G_THREAD_CF (thread_yield, (void)0, ())
-#define g_thread_exit()               G_THREAD_CF (thread_exit, (void)0, ())
-
-GThread* g_thread_create (GThreadFunc            thread_func,
-                          gpointer               arg,
-                          gulong                 stack_size,
-                          gboolean               joinable,
-                          gboolean               bound,
-                          GThreadPriority        priority,
-                          GError               **error);
-GThread* g_thread_self (void);
-void g_thread_join (GThread *thread);
-void g_thread_set_priority (GThread         *thread,
-                            GThreadPriority  priority);
+
+GThread* g_thread_create       (GThreadFunc            thread_func,
+                                gpointer               arg,
+                                gulong                 stack_size,
+                                gboolean               joinable,
+                                gboolean               bound,
+                                GThreadPriority        priority,
+                                GError               **error);
+GThread* g_thread_self         (void);
+void     g_thread_exit         (gpointer               retval);
+gpointer g_thread_join         (GThread               *thread);
+
+void     g_thread_set_priority (GThread               *thread,
+                                GThreadPriority        priority);
 
 /* GStaticMutexes can be statically initialized with the value
  * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
index af62d89..9cfba54 100644 (file)
@@ -53,15 +53,16 @@ G_LOCK_DEFINE_STATIC (unused_threads);
 static GMutex *inform_mutex = NULL;
 static GCond *inform_cond = NULL;
 
-static void g_thread_pool_free_internal (GRealThreadPool* pool);
-static void g_thread_pool_thread_proxy (gpointer data);
-static void g_thread_pool_start_thread (GRealThreadPool* pool, GError **error);
-static void g_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool);
+static void     g_thread_pool_free_internal (GRealThreadPool* pool);
+static gpointer g_thread_pool_thread_proxy (gpointer data);
+static void     g_thread_pool_start_thread (GRealThreadPool* pool, 
+                                           GError **error);
+static void     g_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool);
 
 #define g_thread_should_run(pool, len) \
   ((pool)->running || (!(pool)->immediate && (len) > 0))
 
-static void 
+static gpointer 
 g_thread_pool_thread_proxy (gpointer data)
 {
   GRealThreadPool *pool = data;
@@ -174,7 +175,7 @@ g_thread_pool_thread_proxy (gpointer data)
              G_UNLOCK (unused_threads);
              g_async_queue_unlock (unused_queue);
              /* Stop this thread */
-             return;      
+             return NULL;      
            }
          unused_threads++;
          G_UNLOCK (unused_threads);
@@ -189,7 +190,7 @@ g_thread_pool_thread_proxy (gpointer data)
          
          if (pool == stop_this_thread_marker)
            /* Stop this thread */
-           return;
+           return NULL;
          
          g_async_queue_lock (pool->queue);
 
@@ -198,6 +199,7 @@ g_thread_pool_thread_proxy (gpointer data)
            * known to the pool, before itself can do it. */
        }
     }
+  return NULL;
 }
 
 static void
diff --git a/gmain.c b/gmain.c
index 1fa20fe..10905a2 100644 (file)
--- a/gmain.c
+++ b/gmain.c
@@ -544,9 +544,6 @@ typedef struct _GRealThread GRealThread;
 struct  _GRealThread
 {
   GThread thread;
-  GThreadFunc func;
-  gpointer arg;
-  gpointer private_data;
   GMainContext *context;
 };
 
index 8ee0c99..e3b8a5b 100644 (file)
--- a/gthread.c
+++ b/gthread.c
@@ -74,10 +74,9 @@ typedef struct _GRealThread GRealThread;
 struct  _GRealThread
 {
   GThread thread;
-  GThreadFunc func;
-  gpointer arg;
-  gpointer private_data;
   GMainContext *context;
+  gpointer private_data;
+  gpointer retval;
   GSystemThread system_thread;
 #ifdef G_THREAD_USE_PID_SURROGATE
   pid_t pid;
@@ -512,7 +511,7 @@ g_thread_fail (void)
   g_error ("The thread system is not yet initialized.");
 }
 
-static void 
+static gpointer
 g_thread_create_proxy (gpointer data)
 {
   GRealThread* thread = data;
@@ -527,7 +526,7 @@ g_thread_create_proxy (gpointer data)
   g_private_set (g_thread_specific_private, data);
 
   /* the lock makes sure, that thread->system_thread is written,
-     before thread->func is called. See g_thread_create. */
+     before thread->thread.func is called. See g_thread_create. */
   G_LOCK (g_thread);
   G_UNLOCK (g_thread);
  
@@ -536,7 +535,9 @@ g_thread_create_proxy (gpointer data)
     SET_PRIO (thread->pid, thread->thread.priority);
 #endif /* G_THREAD_USE_PID_SURROGATE */
 
-  thread->func (thread->arg);
+  thread->retval = thread->thread.func (thread->thread.arg);
+
+  return NULL;
 }
 
 GThread* 
@@ -557,8 +558,8 @@ g_thread_create (GThreadFunc                 thread_func,
   result->thread.joinable = joinable;
   result->thread.bound = bound;
   result->thread.priority = priority;
-  result->func = thread_func;
-  result->arg = arg;
+  result->thread.func = thread_func;
+  result->thread.arg = arg;
   result->private_data = NULL; 
   result->context = NULL;
   G_LOCK (g_thread);
@@ -578,18 +579,29 @@ g_thread_create (GThreadFunc               thread_func,
   return (GThread*) result;
 }
 
-void 
+void
+g_thread_exit (gpointer retval)
+{
+  GRealThread* real = (GRealThread*) g_thread_self ();
+  real->retval = retval;
+  G_THREAD_CF (thread_exit, (void)0, ());
+}
+
+gpointer
 g_thread_join (GThread* thread)
 {
   GRealThread* real = (GRealThread*) thread;
-  
+  gpointer retval;
 
-  g_return_if_fail (thread);
-  g_return_if_fail (thread->joinable);
-  g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
+  g_return_val_if_fail (thread, NULL);
+  g_return_val_if_fail (thread->joinable, NULL);
+  g_return_val_if_fail (!g_system_thread_equal (real->system_thread, 
+                                               zero_thread), NULL);
 
   G_THREAD_UF (thread_join, (&real->system_thread));
 
+  retval = real->retval;
+
   G_LOCK (g_thread);
   g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
   G_UNLOCK (g_thread);
@@ -599,10 +611,12 @@ g_thread_join (GThread* thread)
   g_system_thread_assign (real->system_thread, zero_thread);
 
   /* the thread structure for non-joinable threads is freed upon
-     thread end. We free the memory here. This will leave loose end,
+     thread end. We free the memory here. This will leave loose end,
      if a joinable thread is not joined. */
 
   g_free (thread);
+
+  return retval;
 }
 
 void
@@ -642,8 +656,8 @@ g_thread_self (void)
       thread->thread.bound = TRUE; /* This isn't important at all */
       thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
                                                             just a guess */
-      thread->func = NULL;
-      thread->arg = NULL;
+      thread->thread.func = NULL;
+      thread->thread.arg = NULL;
       thread->private_data = NULL;
       thread->context = NULL;
 
index 2f147b4..6a1bfba 100644 (file)
--- a/gthread.h
+++ b/gthread.h
@@ -43,7 +43,7 @@ typedef enum
   G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */
 } GThreadError;
 
-typedef void            (*GThreadFunc)          (gpointer       value);
+typedef gpointer (*GThreadFunc) (gpointer value);
 
 typedef enum
 {
@@ -59,6 +59,8 @@ struct  _GThread
   gboolean joinable;
   gboolean bound;
   GThreadPriority priority;
+  GThreadFunc func;
+  gpointer arg;
 };
 
 typedef struct _GMutex          GMutex;
@@ -191,19 +193,20 @@ GMutex* g_static_mutex_get_mutex_impl   (GMutex **mutex);
                                                         (GPrivate*) (value)), \
                                                        (private_key, value))
 #define g_thread_yield()              G_THREAD_CF (thread_yield, (void)0, ())
-#define g_thread_exit()               G_THREAD_CF (thread_exit, (void)0, ())
-
-GThread* g_thread_create (GThreadFunc            thread_func,
-                          gpointer               arg,
-                          gulong                 stack_size,
-                          gboolean               joinable,
-                          gboolean               bound,
-                          GThreadPriority        priority,
-                          GError               **error);
-GThread* g_thread_self (void);
-void g_thread_join (GThread *thread);
-void g_thread_set_priority (GThread         *thread,
-                            GThreadPriority  priority);
+
+GThread* g_thread_create       (GThreadFunc            thread_func,
+                                gpointer               arg,
+                                gulong                 stack_size,
+                                gboolean               joinable,
+                                gboolean               bound,
+                                GThreadPriority        priority,
+                                GError               **error);
+GThread* g_thread_self         (void);
+void     g_thread_exit         (gpointer               retval);
+gpointer g_thread_join         (GThread               *thread);
+
+void     g_thread_set_priority (GThread               *thread,
+                                GThreadPriority        priority);
 
 /* GStaticMutexes can be statically initialized with the value
  * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
index af62d89..9cfba54 100644 (file)
@@ -53,15 +53,16 @@ G_LOCK_DEFINE_STATIC (unused_threads);
 static GMutex *inform_mutex = NULL;
 static GCond *inform_cond = NULL;
 
-static void g_thread_pool_free_internal (GRealThreadPool* pool);
-static void g_thread_pool_thread_proxy (gpointer data);
-static void g_thread_pool_start_thread (GRealThreadPool* pool, GError **error);
-static void g_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool);
+static void     g_thread_pool_free_internal (GRealThreadPool* pool);
+static gpointer g_thread_pool_thread_proxy (gpointer data);
+static void     g_thread_pool_start_thread (GRealThreadPool* pool, 
+                                           GError **error);
+static void     g_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool);
 
 #define g_thread_should_run(pool, len) \
   ((pool)->running || (!(pool)->immediate && (len) > 0))
 
-static void 
+static gpointer 
 g_thread_pool_thread_proxy (gpointer data)
 {
   GRealThreadPool *pool = data;
@@ -174,7 +175,7 @@ g_thread_pool_thread_proxy (gpointer data)
              G_UNLOCK (unused_threads);
              g_async_queue_unlock (unused_queue);
              /* Stop this thread */
-             return;      
+             return NULL;      
            }
          unused_threads++;
          G_UNLOCK (unused_threads);
@@ -189,7 +190,7 @@ g_thread_pool_thread_proxy (gpointer data)
          
          if (pool == stop_this_thread_marker)
            /* Stop this thread */
-           return;
+           return NULL;
          
          g_async_queue_lock (pool->queue);
 
@@ -198,6 +199,7 @@ g_thread_pool_thread_proxy (gpointer data)
            * known to the pool, before itself can do it. */
        }
     }
+  return NULL;
 }
 
 static void
index 5aba25e..b2e9824 100644 (file)
@@ -123,7 +123,7 @@ timeout_callback (gpointer data)
   return TRUE;
 }
 
-void
+gpointer
 adder_thread (gpointer data)
 {
   GMainContext *context;
@@ -179,6 +179,8 @@ adder_thread (gpointer data)
   g_mutex_unlock (context_array_mutex);
 
   cleanup_crawlers (context);
+
+  return NULL;
 }
 
 void
index 3e689b5..20713d3 100644 (file)
@@ -6,7 +6,7 @@ static GMutex* test_g_mutex_mutex = NULL;
 static guint test_g_mutex_int = 0;
 G_LOCK_DEFINE_STATIC (test_g_mutex);
 
-static void
+static gpointer
 test_g_mutex_thread (gpointer data)
 {
   g_assert (GPOINTER_TO_INT (data) == 42);
@@ -15,6 +15,8 @@ test_g_mutex_thread (gpointer data)
   g_mutex_lock (test_g_mutex_mutex);
   g_assert (test_g_mutex_int == 42);
   g_mutex_unlock (test_g_mutex_mutex);
+
+  return GINT_TO_POINTER (41);
 }
 
 static void
@@ -32,7 +34,7 @@ test_g_mutex (void)
   test_g_mutex_int = 42;
   G_UNLOCK (test_g_mutex);
   g_mutex_unlock (test_g_mutex_mutex);
-  g_thread_join (thread);
+  g_assert (GPOINTER_TO_INT (g_thread_join (thread)) == 41);
   g_mutex_free (test_g_mutex_mutex);
 }
 
@@ -41,7 +43,7 @@ test_g_mutex (void)
 static GStaticRecMutex test_g_static_rec_mutex_mutex = G_STATIC_REC_MUTEX_INIT;
 static guint test_g_static_rec_mutex_int = 0;
 
-static void
+static gpointer
 test_g_static_rec_mutex_thread (gpointer data)
 {
   g_assert (GPOINTER_TO_INT (data) == 42);
@@ -52,6 +54,11 @@ test_g_static_rec_mutex_thread (gpointer data)
   g_assert (test_g_static_rec_mutex_int == 42);
   g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex);
   g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex);
+
+  g_thread_exit (GINT_TO_POINTER (43));
+  
+  g_assert_not_reached ();
+  return NULL;
 }
 
 static void
@@ -74,7 +81,8 @@ test_g_static_rec_mutex (void)
   g_static_rec_mutex_lock (&test_g_static_rec_mutex_mutex);
   test_g_static_rec_mutex_int = 0;  
   g_static_rec_mutex_unlock (&test_g_static_rec_mutex_mutex);
-  g_thread_join (thread);
+
+  g_assert (GPOINTER_TO_INT (g_thread_join (thread)) == 43);
 }
 
 /* GStaticPrivate */
@@ -106,7 +114,7 @@ test_g_static_private_destructor (gpointer data)
 }
 
 
-static void
+static gpointer
 test_g_static_private_thread (gpointer data)
 {
   guint number = GPOINTER_TO_INT (data);
@@ -157,6 +165,8 @@ test_g_static_private_thread (gpointer data)
       g_usleep (G_USEC_PER_SEC / 5);
       g_assert (number * 2 == *private2);      
     }
+
+  return GINT_TO_POINTER (GPOINTER_TO_INT (data) * 3);
 }
 
 static void
@@ -186,9 +196,8 @@ test_g_static_private (void)
   test_g_static_private_ready = 0;
 
   for (i = 0; i < THREADS; i++)
-    {
-      g_thread_join (threads[i]);
-    }
+    g_assert (GPOINTER_TO_INT (g_thread_join (threads[i])) == i * 3);
+    
   g_assert (test_g_static_private_counter == 0); 
 }
 
@@ -201,7 +210,7 @@ G_LOCK_DEFINE (test_g_static_rw_lock_state);
 static gboolean test_g_static_rw_lock_run = TRUE; 
 static GStaticRWLock test_g_static_rw_lock_lock = G_STATIC_RW_LOCK_INIT;
 
-static void
+static gpointer
 test_g_static_rw_lock_thread (gpointer data)
 {
   while (test_g_static_rw_lock_run)
@@ -249,6 +258,7 @@ test_g_static_rw_lock_thread (gpointer data)
          g_static_rw_lock_writer_unlock (&test_g_static_rw_lock_lock);
        }
     }
+  return NULL;
 }
 
 static void