/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * gthread.c: MT safety related functions
 * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
 *                Owen Taylor
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/* Prelude {{{1 ----------------------------------------------------------- */

/*
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/.
 */

/*
 * MT safe
 */

/* implement gthread.h's inline functions */
#define G_IMPLEMENT_INLINES 1
#define __G_THREAD_C__

#include "config.h"

#include "gthread.h"
#include "gthreadprivate.h"

#include <string.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifndef G_OS_WIN32
#include <sys/time.h>
#include <time.h>
#else
#include <windows.h>
#endif /* G_OS_WIN32 */

#include "gslice.h"
#include "gstrfuncs.h"
#include "gtestutils.h"

/**
 * SECTION:threads
 * @title: Threads
 * @short_description: portable support for threads, mutexes, locks,
 *     conditions and thread private data
 * @see_also: #GThreadPool, #GAsyncQueue
 *
 * Threads act almost like processes, but unlike processes all threads
 * of one process share the same memory. This is good, as it provides
 * easy communication between the involved threads via this shared
 * memory, and it is bad, because strange things (so called
 * "Heisenbugs") might happen if the program is not carefully designed.
 * In particular, due to the concurrent nature of threads, no
 * assumptions on the order of execution of code running in different
 * threads can be made, unless order is explicitly forced by the
 * programmer through synchronization primitives.
 *
 * The aim of the thread-related functions in GLib is to provide a
 * portable means for writing multi-threaded software. There are
 * primitives for mutexes to protect the access to portions of memory
 * (#GMutex, #GRecMutex and #GRWLock). There is a facility to use
 * individual bits for locks (g_bit_lock()). There are primitives
 * for condition variables to allow synchronization of threads (#GCond).
 * There are primitives for thread-private data - data that every
 * thread has a private instance of (#GPrivate). There are facilities
 * for one-time initialization (#GOnce, g_once_init_enter()). Finally,
 * there are primitives to create and manage threads (#GThread).
 *
 * The GLib threading system used to be initialized with g_thread_init().
 * This is no longer necessary. Since version 2.32, the GLib threading
 * system is automatically initialized at the start of your program,
 * and all thread-creation functions and synchronization primitives
 * are available right away.
 *
 * Note that it is not safe to assume that your program has no threads
 * even if you don't call g_thread_new() yourself. GLib and GIO can
 * and will create threads for their own purposes in some cases, such
 * as when using g_unix_signal_source_new() or when using GDBus.
 *
 * Originally, UNIX did not have threads, and therefore some traditional
 * UNIX APIs are problematic in threaded programs. Some notable examples
 * are
 * <itemizedlist>
 *   <listitem>
 *     C library functions that return data in statically allocated
 *     buffers, such as strtok() or strerror(). For many of these,
 *     there are thread-safe variants with a _r suffix, or you can
 *     look at corresponding GLib APIs (like g_strsplit() or g_strerror()).
 *   </listitem>
 *   <listitem>
 *     setenv() and unsetenv() manipulate the process environment in
 *     a not thread-safe way, and may interfere with getenv() calls
 *     in other threads. Note that getenv() calls may be
 *     <quote>hidden</quote> behind other APIs. For example, GNU gettext()
 *     calls getenv() under the covers. In general, it is best to treat
 *     the environment as readonly. If you absolutely have to modify the
 *     environment, do it early in main(), when no other threads are around yet.
 *   </listitem>
 *   <listitem>
 *     setlocale() changes the locale for the entire process, affecting
 *     all threads. Temporary changes to the locale are often made to
 *     change the behavior of string scanning or formatting functions
 *     like scanf() or printf(). GLib offers a number of string APIs
 *     (like g_ascii_formatd() or g_ascii_strtod()) that can often be
 *     used as an alternative. Or you can use the uselocale() function
 *     to change the locale only for the current thread.
 *   </listitem>
 *   <listitem>
 *     fork() only takes the calling thread into the child's copy of the
 *     process image.  If other threads were executing in critical
 *     sections they could have left mutexes locked which could easily
 *     cause deadlocks in the new child.  For this reason, you should
 *     call exit() or exec() as soon as possible in the child and only
 *     make signal-safe library calls before that.
 *   </listitem>
 *   <listitem>
 *     daemon() uses fork() in a way contrary to what is described
 *     above.  It should not be used with GLib programs.
 *   </listitem>
 * </itemizedlist>
 *
 * GLib itself is internally completely thread-safe (all global data is
 * automatically locked), but individual data structure instances are
 * not automatically locked for performance reasons. For example,
 * you must coordinate accesses to the same #GHashTable from multiple
 * threads. The two notable exceptions from this rule are #GMainLoop
 * and #GAsyncQueue, which <emphasis>are</emphasis> thread-safe and
 * need no further application-level locking to be accessed from
 * multiple threads. Most refcounting functions such as g_object_ref()
 * are also thread-safe.
 */

/* G_LOCK Documentation {{{1 ---------------------------------------------- */

/**
 * G_LOCK_DEFINE:
 * @name: the name of the lock
 *
 * The <literal>G_LOCK_*</literal> macros provide a convenient interface to #GMutex.
 * #G_LOCK_DEFINE defines a lock. It can appear in any place where
 * variable definitions may appear in programs, i.e. in the first block
 * of a function or outside of functions. The @name parameter will be
 * mangled to get the name of the #GMutex. This means that you
 * can use names of existing variables as the parameter - e.g. the name
 * of the variable you intend to protect with the lock. Look at our
 * <function>give_me_next_number()</function> example using the
 * <literal>G_LOCK_*</literal> macros:
 *
 * <example>
 *  <title>Using the <literal>G_LOCK_*</literal> convenience macros</title>
 *  <programlisting>
 *   G_LOCK_DEFINE (current_number);
 *
 *   int
 *   give_me_next_number (void)
 *   {
 *     static int current_number = 0;
 *     int ret_val;
 *
 *     G_LOCK (current_number);
 *     ret_val = current_number = calc_next_number (current_number);
 *     G_UNLOCK (current_number);
 *
 *     return ret_val;
 *   }
 *  </programlisting>
 * </example>
 */

/**
 * G_LOCK_DEFINE_STATIC:
 * @name: the name of the lock
 *
 * This works like #G_LOCK_DEFINE, but it creates a static object.
 */

/**
 * G_LOCK_EXTERN:
 * @name: the name of the lock
 *
 * This declares a lock, that is defined with #G_LOCK_DEFINE in another
 * module.
 */

/**
 * G_LOCK:
 * @name: the name of the lock
 *
 * Works like g_mutex_lock(), but for a lock defined with
 * #G_LOCK_DEFINE.
 */

/**
 * G_TRYLOCK:
 * @name: the name of the lock
 * @Returns: %TRUE, if the lock could be locked.
 *
 * Works like g_mutex_trylock(), but for a lock defined with
 * #G_LOCK_DEFINE.
 */

/**
 * G_UNLOCK:
 * @name: the name of the lock
 *
 * Works like g_mutex_unlock(), but for a lock defined with
 * #G_LOCK_DEFINE.
 */

/* GMutex Documentation {{{1 ------------------------------------------ */

/**
 * GMutex:
 *
 * The #GMutex struct is an opaque data structure to represent a mutex
 * (mutual exclusion). It can be used to protect data against shared
 * access. Take for example the following function:
 *
 * <example>
 *  <title>A function which will not work in a threaded environment</title>
 *  <programlisting>
 *   int
 *   give_me_next_number (void)
 *   {
 *     static int current_number = 0;
 *
 *     /<!-- -->* now do a very complicated calculation to calculate the new
 *      * number, this might for example be a random number generator
 *      *<!-- -->/
 *     current_number = calc_next_number (current_number);
 *
 *     return current_number;
 *   }
 *  </programlisting>
 * </example>
 *
 * It is easy to see that this won't work in a multi-threaded
 * application. There current_number must be protected against shared
 * access. A #GMutex can be used as a solution to this problem:
 *
 * <example>
 *  <title>Using GMutex to protected a shared variable</title>
 *  <programlisting>
 *   int
 *   give_me_next_number (void)
 *   {
 *     static GMutex mutex;
 *     static int current_number = 0;
 *     int ret_val;
 *
 *     g_mutex_lock (&amp;mutex);
 *     ret_val = current_number = calc_next_number (current_number);
 *     g_mutex_unlock (&amp;mutex);
 *
 *     return ret_val;
 *   }
 *  </programlisting>
 * </example>
 *
 * Notice that the #GMutex is not initialised to any particular value.
 * Its placement in static storage ensures that it will be initialised
 * to all-zeros, which is appropriate.
 *
 * If a #GMutex is placed in other contexts (eg: embedded in a struct)
 * then it must be explicitly initialised using g_mutex_init().
 *
 * A #GMutex should only be accessed via <function>g_mutex_</function>
 * functions.
 */

/* GRecMutex Documentation {{{1 -------------------------------------- */

/**
 * GRecMutex:
 *
 * The GRecMutex struct is an opaque data structure to represent a
 * recursive mutex. It is similar to a #GMutex with the difference
 * that it is possible to lock a GRecMutex multiple times in the same
 * thread without deadlock. When doing so, care has to be taken to
 * unlock the recursive mutex as often as it has been locked.
 *
 * If a #GRecMutex is allocated in static storage then it can be used
 * without initialisation.  Otherwise, you should call
 * g_rec_mutex_init() on it and g_rec_mutex_clear() when done.
 *
 * A GRecMutex should only be accessed with the
 * <function>g_rec_mutex_</function> functions.
 *
 * Since: 2.32
 */

/* GRWLock Documentation {{{1 ---------------------------------------- */

/**
 * GRWLock:
 *
 * The GRWLock struct is an opaque data structure to represent a
 * reader-writer lock. It is similar to a #GMutex in that it allows
 * multiple threads to coordinate access to a shared resource.
 *
 * The difference to a mutex is that a reader-writer lock discriminates
 * between read-only ('reader') and full ('writer') access. While only
 * one thread at a time is allowed write access (by holding the 'writer'
 * lock via g_rw_lock_writer_lock()), multiple threads can gain
 * simultaneous read-only access (by holding the 'reader' lock via
 * g_rw_lock_reader_lock()).
 *
 * <example>
 *  <title>An array with access functions</title>
 *  <programlisting>
 *   GRWLock lock;
 *   GPtrArray *array;
 *
 *   gpointer
 *   my_array_get (guint index)
 *   {
 *     gpointer retval = NULL;
 *
 *     if (!array)
 *       return NULL;
 *
 *     g_rw_lock_reader_lock (&amp;lock);
 *     if (index &lt; array->len)
 *       retval = g_ptr_array_index (array, index);
 *     g_rw_lock_reader_unlock (&amp;lock);
 *
 *     return retval;
 *   }
 *
 *   void
 *   my_array_set (guint index, gpointer data)
 *   {
 *     g_rw_lock_writer_lock (&amp;lock);
 *
 *     if (!array)
 *       array = g_ptr_array_new (<!-- -->);
 *
 *     if (index >= array->len)
 *       g_ptr_array_set_size (array, index+1);
 *     g_ptr_array_index (array, index) = data;
 *
 *     g_rw_lock_writer_unlock (&amp;lock);
 *   }
 *  </programlisting>
 *  <para>
 *    This example shows an array which can be accessed by many readers
 *    (the <function>my_array_get()</function> function) simultaneously,
 *    whereas the writers (the <function>my_array_set()</function>
 *    function) will only be allowed once at a time and only if no readers
 *    currently access the array. This is because of the potentially
 *    dangerous resizing of the array. Using these functions is fully
 *    multi-thread safe now.
 *  </para>
 * </example>
 *
 * If a #GRWLock is allocated in static storage then it can be used
 * without initialisation.  Otherwise, you should call
 * g_rw_lock_init() on it and g_rw_lock_clear() when done.
 *
 * A GRWLock should only be accessed with the
 * <function>g_rw_lock_</function> functions.
 *
 * Since: 2.32
 */

/* GCond Documentation {{{1 ------------------------------------------ */

/**
 * GCond:
 *
 * The #GCond struct is an opaque data structure that represents a
 * condition. Threads can block on a #GCond if they find a certain
 * condition to be false. If other threads change the state of this
 * condition they signal the #GCond, and that causes the waiting
 * threads to be woken up.
 *
 * Consider the following example of a shared variable.  One or more
 * threads can wait for data to be published to the variable and when
 * another thread publishes the data, it can signal one of the waiting
 * threads to wake up to collect the data.
 *
 * <example>
 *  <title>
 *   Using GCond to block a thread until a condition is satisfied
 *  </title>
 *  <programlisting>
 *   gpointer current_data = NULL;
 *   GMutex data_mutex;
 *   GCond data_cond;
 *
 *   void
 *   push_data (gpointer data)
 *   {
 *     g_mutex_lock (&data_mutex);
 *     current_data = data;
 *     g_cond_signal (&data_cond);
 *     g_mutex_unlock (&data_mutex);
 *   }
 *
 *   gpointer
 *   pop_data (void)
 *   {
 *     gpointer data;
 *
 *     g_mutex_lock (&data_mutex);
 *     while (!current_data)
 *       g_cond_wait (&data_cond, &data_mutex);
 *     data = current_data;
 *     current_data = NULL;
 *     g_mutex_unlock (&data_mutex);
 *
 *     return data;
 *   }
 *  </programlisting>
 * </example>
 *
 * Whenever a thread calls pop_data() now, it will wait until
 * current_data is non-%NULL, i.e. until some other thread
 * has called push_data().
 *
 * The example shows that use of a condition variable must always be
 * paired with a mutex.  Without the use of a mutex, there would be a
 * race between the check of <varname>current_data</varname> by the
 * while loop in <function>pop_data</function> and waiting.
 * Specifically, another thread could set <varname>pop_data</varname>
 * after the check, and signal the cond (with nobody waiting on it)
 * before the first thread goes to sleep.  #GCond is specifically useful
 * for its ability to release the mutex and go to sleep atomically.
 *
 * It is also important to use the g_cond_wait() and g_cond_wait_until()
 * functions only inside a loop which checks for the condition to be
 * true.  See g_cond_wait() for an explanation of why the condition may
 * not be true even after it returns.
 *
 * If a #GCond is allocated in static storage then it can be used
 * without initialisation.  Otherwise, you should call g_cond_init() on
 * it and g_cond_clear() when done.
 *
 * A #GCond should only be accessed via the <function>g_cond_</function>
 * functions.
 */

/* GThread Documentation {{{1 ---------------------------------------- */

/**
 * GThread:
 *
 * The #GThread struct represents a running thread. This struct
 * is returned by g_thread_new() or g_thread_try_new(). You can
 * obtain the #GThread struct representing the current thead by
 * calling g_thread_self().
 *
 * GThread is refcounted, see g_thread_ref() and g_thread_unref().
 * The thread represented by it holds a reference while it is running,
 * and g_thread_join() consumes the reference that it is given, so
 * it is normally not necessary to manage GThread references
 * explicitly.
 *
 * The structure is opaque -- none of its fields may be directly
 * accessed.
 */

/**
 * GThreadFunc:
 * @data: data passed to the thread
 *
 * Specifies the type of the @func functions passed to g_thread_new()
 * or g_thread_try_new().
 *
 * Returns: the return value of the thread
 */

/**
 * g_thread_supported:
 *
 * This macro returns %TRUE if the thread system is initialized,
 * and %FALSE if it is not.
 *
 * For language bindings, g_thread_get_initialized() provides
 * the same functionality as a function.
 *
 * Returns: %TRUE, if the thread system is initialized
 */

/* GThreadError {{{1 ------------------------------------------------------- */
/**
 * GThreadError:
 * @G_THREAD_ERROR_AGAIN: a thread couldn't be created due to resource
 *                        shortage. Try again later.
 *
 * Possible errors of thread related functions.
 **/

/**
 * G_THREAD_ERROR:
 *
 * The error domain of the GLib thread subsystem.
 **/
GQuark
g_thread_error_quark (void)
{
  return g_quark_from_static_string ("g_thread_error");
}

/* Local Data {{{1 -------------------------------------------------------- */

static GMutex    g_once_mutex;
static GCond     g_once_cond;
static GSList   *g_once_init_list = NULL;

static void g_thread_cleanup (gpointer data);
static GPrivate     g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup);

G_LOCK_DEFINE_STATIC (g_thread_new);

/* GOnce {{{1 ------------------------------------------------------------- */

/**
 * GOnce:
 * @status: the status of the #GOnce
 * @retval: the value returned by the call to the function, if @status
 *          is %G_ONCE_STATUS_READY
 *
 * A #GOnce struct controls a one-time initialization function. Any
 * one-time initialization function must have its own unique #GOnce
 * struct.
 *
 * Since: 2.4
 */

/**
 * G_ONCE_INIT:
 *
 * A #GOnce must be initialized with this macro before it can be used.
 *
 * |[
 *   GOnce my_once = G_ONCE_INIT;
 * ]|
 *
 * Since: 2.4
 */

/**
 * GOnceStatus:
 * @G_ONCE_STATUS_NOTCALLED: the function has not been called yet.
 * @G_ONCE_STATUS_PROGRESS: the function call is currently in progress.
 * @G_ONCE_STATUS_READY: the function has been called.
 *
 * The possible statuses of a one-time initialization function
 * controlled by a #GOnce struct.
 *
 * Since: 2.4
 */

/**
 * g_once:
 * @once: a #GOnce structure
 * @func: the #GThreadFunc function associated to @once. This function
 *        is called only once, regardless of the number of times it and
 *        its associated #GOnce struct are passed to g_once().
 * @arg: data to be passed to @func
 *
 * The first call to this routine by a process with a given #GOnce
 * struct calls @func with the given argument. Thereafter, subsequent
 * calls to g_once()  with the same #GOnce struct do not call @func
 * again, but return the stored result of the first call. On return
 * from g_once(), the status of @once will be %G_ONCE_STATUS_READY.
 *
 * For example, a mutex or a thread-specific data key must be created
 * exactly once. In a threaded environment, calling g_once() ensures
 * that the initialization is serialized across multiple threads.
 *
 * Calling g_once() recursively on the same #GOnce struct in
 * @func will lead to a deadlock.
 *
 * |[
 *   gpointer
 *   get_debug_flags (void)
 *   {
 *     static GOnce my_once = G_ONCE_INIT;
 *
 *     g_once (&my_once, parse_debug_flags, NULL);
 *
 *     return my_once.retval;
 *   }
 * ]|
 *
 * Since: 2.4
 */
gpointer
g_once_impl (GOnce       *once,
	     GThreadFunc  func,
	     gpointer     arg)
{
  g_mutex_lock (&g_once_mutex);

  while (once->status == G_ONCE_STATUS_PROGRESS)
    g_cond_wait (&g_once_cond, &g_once_mutex);

  if (once->status != G_ONCE_STATUS_READY)
    {
      once->status = G_ONCE_STATUS_PROGRESS;
      g_mutex_unlock (&g_once_mutex);

      once->retval = func (arg);

      g_mutex_lock (&g_once_mutex);
      once->status = G_ONCE_STATUS_READY;
      g_cond_broadcast (&g_once_cond);
    }

  g_mutex_unlock (&g_once_mutex);

  return once->retval;
}

/**
 * g_once_init_enter:
 * @location: location of a static initializable variable containing 0
 *
 * Function to be called when starting a critical initialization
 * section. The argument @location must point to a static
 * 0-initialized variable that will be set to a value other than 0 at
 * the end of the initialization section. In combination with
 * g_once_init_leave() and the unique address @value_location, it can
 * be ensured that an initialization section will be executed only once
 * during a program's life time, and that concurrent threads are
 * blocked until initialization completed. To be used in constructs
 * like this:
 *
 * |[
 *   static gsize initialization_value = 0;
 *
 *   if (g_once_init_enter (&amp;initialization_value))
 *     {
 *       gsize setup_value = 42; /&ast;* initialization code here *&ast;/
 *
 *       g_once_init_leave (&amp;initialization_value, setup_value);
 *     }
 *
 *   /&ast;* use initialization_value here *&ast;/
 * ]|
 *
 * Returns: %TRUE if the initialization section should be entered,
 *     %FALSE and blocks otherwise
 *
 * Since: 2.14
 */
gboolean
(g_once_init_enter) (volatile void *location)
{
  volatile gsize *value_location = location;
  gboolean need_init = FALSE;
  g_mutex_lock (&g_once_mutex);
  if (g_atomic_pointer_get (value_location) == NULL)
    {
      if (!g_slist_find (g_once_init_list, (void*) value_location))
        {
          need_init = TRUE;
          g_once_init_list = g_slist_prepend (g_once_init_list, (void*) value_location);
        }
      else
        do
          g_cond_wait (&g_once_cond, &g_once_mutex);
        while (g_slist_find (g_once_init_list, (void*) value_location));
    }
  g_mutex_unlock (&g_once_mutex);
  return need_init;
}

/**
 * g_once_init_leave:
 * @location: location of a static initializable variable containing 0
 * @result: new non-0 value for *@value_location
 *
 * Counterpart to g_once_init_enter(). Expects a location of a static
 * 0-initialized initialization variable, and an initialization value
 * other than 0. Sets the variable to the initialization value, and
 * releases concurrent threads blocking in g_once_init_enter() on this
 * initialization variable.
 *
 * Since: 2.14
 */
void
(g_once_init_leave) (volatile void *location,
                     gsize          result)
{
  volatile gsize *value_location = location;

  g_return_if_fail (g_atomic_pointer_get (value_location) == NULL);
  g_return_if_fail (result != 0);
  g_return_if_fail (g_once_init_list != NULL);

  g_atomic_pointer_set (value_location, result);
  g_mutex_lock (&g_once_mutex);
  g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location);
  g_cond_broadcast (&g_once_cond);
  g_mutex_unlock (&g_once_mutex);
}

/* GThread {{{1 -------------------------------------------------------- */

/**
 * g_thread_ref:
 * @thread: a #GThread
 *
 * Increase the reference count on @thread.
 *
 * Returns: a new reference to @thread
 *
 * Since: 2.32
 */
GThread *
g_thread_ref (GThread *thread)
{
  GRealThread *real = (GRealThread *) thread;

  g_atomic_int_inc (&real->ref_count);

  return thread;
}

/**
 * g_thread_unref:
 * @thread: a #GThread
 *
 * Decrease the reference count on @thread, possibly freeing all
 * resources associated with it.
 *
 * Note that each thread holds a reference to its #GThread while
 * it is running, so it is safe to drop your own reference to it
 * if you don't need it anymore.
 *
 * Since: 2.32
 */
void
g_thread_unref (GThread *thread)
{
  GRealThread *real = (GRealThread *) thread;

  if (g_atomic_int_dec_and_test (&real->ref_count))
    {
      if (real->ours)
        g_system_thread_free (real);
      else
        g_slice_free (GRealThread, real);
    }
}

static void
g_thread_cleanup (gpointer data)
{
  g_thread_unref (data);
}

gpointer
g_thread_proxy (gpointer data)
{
  GRealThread* thread = data;

  g_assert (data);

  /* This has to happen before G_LOCK, as that might call g_thread_self */
  g_private_set (&g_thread_specific_private, data);

  /* The lock makes sure that g_thread_new_internal() has a chance to
   * setup 'func' and 'data' before we make the call.
   */
  G_LOCK (g_thread_new);
  G_UNLOCK (g_thread_new);

  if (thread->name)
    {
      g_system_thread_set_name (thread->name);
      g_free (thread->name);
      thread->name = NULL;
    }

  thread->retval = thread->thread.func (thread->thread.data);

  return NULL;
}

/**
 * g_thread_new:
 * @name: a name for the new thread
 * @func: a function to execute in the new thread
 * @data: an argument to supply to the new thread
 *
 * This function creates a new thread. The new thread starts by invoking
 * @func with the argument data. The thread will run until @func returns
 * or until g_thread_exit() is called from the new thread. The return value
 * of @func becomes the return value of the thread, which can be obtained
 * with g_thread_join().
 *
 * The @name can be useful for discriminating threads in a debugger.
 * Some systems restrict the length of @name to 16 bytes.
 *
 * If the thread can not be created the program aborts. See
 * g_thread_try_new() if you want to attempt to deal with failures.
 *
 * To free the struct returned by this function, use g_thread_unref().
 * Note that g_thread_join() implicitly unrefs the #GThread as well.
 *
 * Returns: the new #GThread
 *
 * Since: 2.32
 */
GThread *
g_thread_new (const gchar *name,
              GThreadFunc  func,
              gpointer     data)
{
  GError *error = NULL;
  GThread *thread;

  thread = g_thread_new_internal (name, g_thread_proxy, func, data, 0, &error);

  if G_UNLIKELY (thread == NULL)
    g_error ("creating thread '%s': %s", name ? name : "", error->message);

  return thread;
}

/**
 * g_thread_try_new:
 * @name: a name for the new thread
 * @func: a function to execute in the new thread
 * @data: an argument to supply to the new thread
 * @error: return location for error, or %NULL
 *
 * This function is the same as g_thread_new() except that
 * it allows for the possibility of failure.
 *
 * If a thread can not be created (due to resource limits),
 * @error is set and %NULL is returned.
 *
 * Returns: the new #GThread, or %NULL if an error occurred
 *
 * Since: 2.32
 */
GThread *
g_thread_try_new (const gchar  *name,
                  GThreadFunc   func,
                  gpointer      data,
                  GError      **error)
{
  return g_thread_new_internal (name, g_thread_proxy, func, data, 0, error);
}

GThread *
g_thread_new_internal (const gchar   *name,
                       GThreadFunc    proxy,
                       GThreadFunc    func,
                       gpointer       data,
                       gsize          stack_size,
                       GError       **error)
{
  GRealThread *thread;

  g_return_val_if_fail (func != NULL, NULL);

  G_LOCK (g_thread_new);
  thread = g_system_thread_new (proxy, stack_size, error);
  if (thread)
    {
      thread->ref_count = 2;
      thread->ours = TRUE;
      thread->thread.joinable = TRUE;
      thread->thread.func = func;
      thread->thread.data = data;
      thread->name = g_strdup (name);
    }
  G_UNLOCK (g_thread_new);

  return (GThread*) thread;
}

/**
 * g_thread_exit:
 * @retval: the return value of this thread
 *
 * Terminates the current thread.
 *
 * If another thread is waiting for us using g_thread_join() then the
 * waiting thread will be woken up and get @retval as the return value
 * of g_thread_join().
 *
 * Calling <literal>g_thread_exit (retval)</literal> is equivalent to
 * returning @retval from the function @func, as given to g_thread_new().
 *
 * <note><para>
 *   You must only call g_thread_exit() from a thread that you created
 *   yourself with g_thread_new() or related APIs.  You must not call
 *   this function from a thread created with another threading library
 *   or or from within a #GThreadPool.
 * </para></note>
 */
void
g_thread_exit (gpointer retval)
{
  GRealThread* real = (GRealThread*) g_thread_self ();

  if G_UNLIKELY (!real->ours)
    g_error ("attempt to g_thread_exit() a thread not created by GLib");

  real->retval = retval;

  g_system_thread_exit ();
}

/**
 * g_thread_join:
 * @thread: a #GThread
 *
 * Waits until @thread finishes, i.e. the function @func, as
 * given to g_thread_new(), returns or g_thread_exit() is called.
 * If @thread has already terminated, then g_thread_join()
 * returns immediately.
 *
 * Any thread can wait for any other thread by calling g_thread_join(),
 * not just its 'creator'. Calling g_thread_join() from multiple threads
 * for the same @thread leads to undefined behaviour.
 *
 * The value returned by @func or given to g_thread_exit() is
 * returned by this function.
 *
 * g_thread_join() consumes the reference to the passed-in @thread.
 * This will usually cause the #GThread struct and associated resources
 * to be freed. Use g_thread_ref() to obtain an extra reference if you
 * want to keep the GThread alive beyond the g_thread_join() call.
 *
 * Returns: the return value of the thread
 */
gpointer
g_thread_join (GThread *thread)
{
  GRealThread *real = (GRealThread*) thread;
  gpointer retval;

  g_return_val_if_fail (thread, NULL);
  g_return_val_if_fail (real->ours, NULL);

  g_system_thread_wait (real);

  retval = real->retval;

  /* Just to make sure, this isn't used any more */
  thread->joinable = 0;

  g_thread_unref (thread);

  return retval;
}

/**
 * g_thread_self:
 *
 * This functions returns the #GThread corresponding to the
 * current thread. Note that this function does not increase
 * the reference count of the returned struct.
 *
 * This function will return a #GThread even for threads that
 * were not created by GLib (i.e. those created by other threading
 * APIs). This may be useful for thread identification purposes
 * (i.e. comparisons) but you must not use GLib functions (such
 * as g_thread_join()) on these threads.
 *
 * Returns: the #GThread representing the current thread
 */
GThread*
g_thread_self (void)
{
  GRealThread* thread = g_private_get (&g_thread_specific_private);

  if (!thread)
    {
      /* If no thread data is available, provide and set one.
       * This can happen for the main thread and for threads
       * that are not created by GLib.
       */
      thread = g_slice_new0 (GRealThread);
      thread->ref_count = 1;

      g_private_set (&g_thread_specific_private, thread);
    }

  return (GThread*) thread;
}

/* Epilogue {{{1 */
/* vim: set foldmethod=marker: */
