/* 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, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

/* we know we are deprecated here, no need for warnings */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include "gmessages.h"
#include "gslice.h"
#include "gmain.h"
#include "gthread.h"
#include "gthreadprivate.h"
#include "deprecated/gthread.h"
#include "garray.h"

#include "gutils.h"

/* {{{1 Documentation */

/**
 * SECTION:threads-deprecated
 * @title: Deprecated thread API
 * @short_description: old thread APIs (for reference only)
 * @see_also: #GThread
 *
 * These APIs are deprecated.  You should not use them in new code.
 * This section remains only to assist with understanding code that was
 * written to use these APIs at some point in the past.
 **/

/**
 * GThreadPriority:
 * @G_THREAD_PRIORITY_LOW: a priority lower than normal
 * @G_THREAD_PRIORITY_NORMAL: the default priority
 * @G_THREAD_PRIORITY_HIGH: a priority higher than normal
 * @G_THREAD_PRIORITY_URGENT: the highest priority
 *
 * Thread priorities.
 *
 * Deprecated:2.32: Thread priorities no longer have any effect.
 */

/**
 * GThreadFunctions:
 * @mutex_new: virtual function pointer for g_mutex_new()
 * @mutex_lock: virtual function pointer for g_mutex_lock()
 * @mutex_trylock: virtual function pointer for g_mutex_trylock()
 * @mutex_unlock: virtual function pointer for g_mutex_unlock()
 * @mutex_free: virtual function pointer for g_mutex_free()
 * @cond_new: virtual function pointer for g_cond_new()
 * @cond_signal: virtual function pointer for g_cond_signal()
 * @cond_broadcast: virtual function pointer for g_cond_broadcast()
 * @cond_wait: virtual function pointer for g_cond_wait()
 * @cond_timed_wait: virtual function pointer for g_cond_timed_wait()
 * @cond_free: virtual function pointer for g_cond_free()
 * @private_new: virtual function pointer for g_private_new()
 * @private_get: virtual function pointer for g_private_get()
 * @private_set: virtual function pointer for g_private_set()
 * @thread_create: virtual function pointer for g_thread_create()
 * @thread_yield: virtual function pointer for g_thread_yield()
 * @thread_join: virtual function pointer for g_thread_join()
 * @thread_exit: virtual function pointer for g_thread_exit()
 * @thread_set_priority: virtual function pointer for
 *                       g_thread_set_priority()
 * @thread_self: virtual function pointer for g_thread_self()
 * @thread_equal: used internally by recursive mutex locks and by some
 *                assertion checks
 *
 * This function table is no longer used by g_thread_init()
 * to initialize the thread system.
 */

/**
 * G_THREADS_IMPL_POSIX:
 *
 * This macro is defined if POSIX style threads are used.
 *
 * Deprecated:2.32:POSIX threads are in use on all non-Windows systems.
 *                 Use G_OS_WIN32 to detect Windows.
 */

/**
 * G_THREADS_IMPL_WIN32:
 *
 * This macro is defined if Windows style threads are used.
 *
 * Deprecated:2.32:Use G_OS_WIN32 to detect Windows.
 */


/* {{{1 Exported Variables */

/* Set this FALSE to have previously-compiled GStaticMutex code use the
 * slow path (ie: call into us) to avoid compatibility problems.
 */
gboolean g_thread_use_default_impl = FALSE;

GThreadFunctions g_thread_functions_for_glib_use =
{
  g_mutex_new,
  g_mutex_lock,
  g_mutex_trylock,
  g_mutex_unlock,
  g_mutex_free,
  g_cond_new,
  g_cond_signal,
  g_cond_broadcast,
  g_cond_wait,
  g_cond_timed_wait,
  g_cond_free,
  g_private_new,
  g_private_get,
  g_private_set,
  NULL,
  g_thread_yield,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
};

static guint64
gettime (void)
{
  return g_get_monotonic_time () * 1000;
}

guint64 (*g_thread_gettime) (void) = gettime;

/* Initialisation {{{1 ---------------------------------------------------- */
gboolean         g_threads_got_initialized = TRUE;

/**
 * g_thread_init:
 * @vtable: a function table of type #GThreadFunctions, that provides
 *     the entry points to the thread system to be used. Since 2.32,
 *     this parameter is ignored and should always be %NULL
 *
 * If you use GLib from more than one thread, you must initialize the
 * thread system by calling g_thread_init().
 *
 * Since version 2.24, calling g_thread_init() multiple times is allowed,
 * but nothing happens except for the first call.
 *
 * Since version 2.32, GLib does not support custom thread implementations
 * anymore and the @vtable parameter is ignored and you should pass %NULL.
 *
 * <note><para>g_thread_init() must not be called directly or indirectly
 * in a callback from GLib. Also no mutexes may be currently locked while
 * calling g_thread_init().</para></note>
 *
 * <note><para>To use g_thread_init() in your program, you have to link
 * with the libraries that the command <command>pkg-config --libs
 * gthread-2.0</command> outputs. This is not the case for all the
 * other thread-related functions of GLib. Those can be used without
 * having to link with the thread libraries.</para></note>
 *
 * Deprecated:2.32: This function is no longer necessary. The GLib
 *     threading system is automatically initialized at the start
 *     of your program.
 */

/**
 * g_thread_get_initialized:
 *
 * Indicates if g_thread_init() has been called.
 *
 * Returns: %TRUE if threads have been initialized.
 *
 * Since: 2.20
 */
gboolean
g_thread_get_initialized (void)
{
  return g_thread_supported ();
}

/* We need this for ABI compatibility */
GLIB_AVAILABLE_IN_ALL
void g_thread_init_glib (void);
void g_thread_init_glib (void) { }

/* Internal variables {{{1 */

static GSList      *g_thread_all_threads = NULL;
static GSList      *g_thread_free_indices = NULL;

/* Protects g_thread_all_threads and g_thread_free_indices */
G_LOCK_DEFINE_STATIC (g_static_mutex);
G_LOCK_DEFINE_STATIC (g_thread);

/* Misc. GThread functions {{{1 */

/**
 * g_thread_set_priority:
 * @thread: a #GThread.
 * @priority: ignored
 *
 * This function does nothing.
 *
 * Deprecated:2.32: Thread priorities no longer have any effect.
 */
void
g_thread_set_priority (GThread         *thread,
                       GThreadPriority  priority)
{
}

/**
 * g_thread_foreach:
 * @thread_func: function to call for all #GThread structures
 * @user_data: second argument to @thread_func
 *
 * Call @thread_func on all #GThreads that have been
 * created with g_thread_create().
 *
 * Note that threads may decide to exit while @thread_func is
 * running, so without intimate knowledge about the lifetime of
 * foreign threads, @thread_func shouldn't access the GThread*
 * pointer passed in as first argument. However, @thread_func will
 * not be called for threads which are known to have exited already.
 *
 * Due to thread lifetime checks, this function has an execution complexity
 * which is quadratic in the number of existing threads.
 *
 * Since: 2.10
 *
 * Deprecated:2.32: There aren't many things you can do with a #GThread,
 *     except comparing it with one that was returned from g_thread_create().
 *     There are better ways to find out if your thread is still alive.
 */
void
g_thread_foreach (GFunc    thread_func,
                  gpointer user_data)
{
  GSList *slist = NULL;
  GRealThread *thread;
  g_return_if_fail (thread_func != NULL);
  /* snapshot the list of threads for iteration */
  G_LOCK (g_thread);
  slist = g_slist_copy (g_thread_all_threads);
  G_UNLOCK (g_thread);
  /* walk the list, skipping non-existent threads */
  while (slist)
    {
      GSList *node = slist;
      slist = node->next;
      /* check whether the current thread still exists */
      G_LOCK (g_thread);
      if (g_slist_find (g_thread_all_threads, node->data))
        thread = node->data;
      else
        thread = NULL;
      G_UNLOCK (g_thread);
      if (thread)
        thread_func (thread, user_data);
      g_slist_free_1 (node);
    }
}

static void
g_enumerable_thread_remove (gpointer data)
{
  GRealThread *thread = data;

  G_LOCK (g_thread);
  g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
  G_UNLOCK (g_thread);
}

GPrivate enumerable_thread_private = G_PRIVATE_INIT (g_enumerable_thread_remove);

static void
g_enumerable_thread_add (GRealThread *thread)
{
  G_LOCK (g_thread);
  g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread);
  G_UNLOCK (g_thread);

  g_private_set (&enumerable_thread_private, thread);
}

static gpointer
g_deprecated_thread_proxy (gpointer data)
{
  GRealThread *real = data;

  g_enumerable_thread_add (real);

  return g_thread_proxy (data);
}

/**
 * g_thread_create:
 * @func: a function to execute in the new thread
 * @data: an argument to supply to the new thread
 * @joinable: should this thread be joinable?
 * @error: return location for error, or %NULL
 *
 * This function creates a new thread.
 *
 * The new thread executes the function @func with the argument @data.
 * If the thread was created successfully, it is returned.
 *
 * @error can be %NULL to ignore errors, or non-%NULL to report errors.
 * The error is set, if and only if the function returns %NULL.
 *
 * This function returns a reference to the created thread only if
 * @joinable is %TRUE.  In that case, you must free this reference by
 * calling g_thread_unref() or g_thread_join().  If @joinable is %FALSE
 * then you should probably not touch the return value.
 *
 * Returns: the new #GThread on success
 *
 * Deprecated:2.32: Use g_thread_new() instead
 */
GThread *
g_thread_create (GThreadFunc   func,
                 gpointer      data,
                 gboolean      joinable,
                 GError      **error)
{
  return g_thread_create_full (func, data, 0, joinable, 0, 0, error);
}

/**
 * g_thread_create_full:
 * @func: a function to execute in the new thread.
 * @data: an argument to supply to the new thread.
 * @stack_size: a stack size for the new thread.
 * @joinable: should this thread be joinable?
 * @bound: ignored
 * @priority: ignored
 * @error: return location for error.
 *
 * This function creates a new thread.
 *
 * Returns: the new #GThread on success.
 *
 * Deprecated:2.32: The @bound and @priority arguments are now ignored.
 * Use g_thread_new().
 */
GThread *
g_thread_create_full (GThreadFunc       func,
                      gpointer          data,
                      gulong            stack_size,
                      gboolean          joinable,
                      gboolean          bound,
                      GThreadPriority   priority,
                      GError          **error)
{
  GThread *thread;

  thread = g_thread_new_internal (NULL, g_deprecated_thread_proxy,
                                  func, data, stack_size, error);

  if (thread && !joinable)
    {
      thread->joinable = FALSE;
      g_thread_unref (thread);
    }

  return thread;
}

/* GOnce {{{1 ------------------------------------------------------------- */
gboolean
g_once_init_enter_impl (volatile gsize *location)
{
  return (g_once_init_enter) (location);
}

/* GStaticMutex {{{1 ------------------------------------------------------ */

/**
 * GStaticMutex:
 *
 * A #GStaticMutex works like a #GMutex.
 *
 * Prior to GLib 2.32, GStaticMutex had the significant advantage
 * that it doesn't need to be created at run-time, but can be defined
 * at compile-time. Since 2.32, #GMutex can be statically allocated
 * as well, and GStaticMutex has been deprecated.
 *
 * Here is a version of our give_me_next_number() example using
 * a GStaticMutex:
 * |[
 *   int
 *   give_me_next_number (void)
 *   {
 *     static int current_number = 0;
 *     int ret_val;
 *     static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
 *
 *     g_static_mutex_lock (&mutex);
 *     ret_val = current_number = calc_next_number (current_number);
 *     g_static_mutex_unlock (&mutex);
 *
 *     return ret_val;
 *   }
 * ]|
 *
 * Sometimes you would like to dynamically create a mutex. If you don't
 * want to require prior calling to g_thread_init(), because your code
 * should also be usable in non-threaded programs, you are not able to
 * use g_mutex_new() and thus #GMutex, as that requires a prior call to
 * g_thread_init(). In theses cases you can also use a #GStaticMutex.
 * It must be initialized with g_static_mutex_init() before using it
 * and freed with with g_static_mutex_free() when not needed anymore to
 * free up any allocated resources.
 *
 * Even though #GStaticMutex is not opaque, it should only be used with
 * the following functions, as it is defined differently on different
 * platforms.
 *
 * All of the g_static_mutex_* functions apart from
 * g_static_mutex_get_mutex() can also be used even if g_thread_init()
 * has not yet been called. Then they do nothing, apart from
 * g_static_mutex_trylock() which does nothing but returning %TRUE.
 *
 * All of the g_static_mutex_* functions are actually macros. Apart from
 * taking their addresses, you can however use them as if they were
 * functions.
 */

/**
 * G_STATIC_MUTEX_INIT:
 *
 * A #GStaticMutex must be initialized with this macro, before it can
 * be used. This macro can used be to initialize a variable, but it
 * cannot be assigned to a variable. In that case you have to use
 * g_static_mutex_init().
 *
 * |[
 * GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;
 * ]|
 **/

/**
 * g_static_mutex_init:
 * @mutex: a #GStaticMutex to be initialized.
 *
 * Initializes @mutex.
 * Alternatively you can initialize it with #G_STATIC_MUTEX_INIT.
 *
 * Deprecated: 2.32: Use g_mutex_init()
 */
void
g_static_mutex_init (GStaticMutex *mutex)
{
  static const GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;

  g_return_if_fail (mutex);

  *mutex = init_mutex;
}

/* IMPLEMENTATION NOTE:
 *
 * On some platforms a GStaticMutex is actually a normal GMutex stored
 * inside of a structure instead of being allocated dynamically.  We can
 * only do this for platforms on which we know, in advance, how to
 * allocate (size) and initialise (value) that memory.
 *
 * On other platforms, a GStaticMutex is nothing more than a pointer to
 * a GMutex.  In that case, the first access we make to the static mutex
 * must first allocate the normal GMutex and store it into the pointer.
 *
 * configure.ac writes macros into glibconfig.h to determine if
 * g_static_mutex_get_mutex() accesses the structure in memory directly
 * (on platforms where we are able to do that) or if it ends up here,
 * where we may have to allocate the GMutex before returning it.
 */

/**
 * g_static_mutex_get_mutex:
 * @mutex: a #GStaticMutex.
 *
 * For some operations (like g_cond_wait()) you must have a #GMutex
 * instead of a #GStaticMutex. This function will return the
 * corresponding #GMutex for @mutex.
 *
 * Returns: the #GMutex corresponding to @mutex.
 *
 * Deprecated: 2.32: Just use a #GMutex
 */
GMutex *
g_static_mutex_get_mutex_impl (GStaticMutex* mutex)
{
  GMutex *result;

  if (!g_thread_supported ())
    return NULL;

  result = g_atomic_pointer_get (&mutex->mutex);

  if (!result)
    {
      G_LOCK (g_static_mutex);

      result = mutex->mutex;
      if (!result)
        {
          result = g_mutex_new ();
          g_atomic_pointer_set (&mutex->mutex, result);
        }

      G_UNLOCK (g_static_mutex);
    }

  return result;
}

/* IMPLEMENTATION NOTE:
 *
 * g_static_mutex_lock(), g_static_mutex_trylock() and
 * g_static_mutex_unlock() are all preprocessor macros that wrap the
 * corresponding g_mutex_*() function around a call to
 * g_static_mutex_get_mutex().
 */

/**
 * g_static_mutex_lock:
 * @mutex: a #GStaticMutex.
 *
 * Works like g_mutex_lock(), but for a #GStaticMutex.
 *
 * Deprecated: 2.32: Use g_mutex_lock()
 */

/**
 * g_static_mutex_trylock:
 * @mutex: a #GStaticMutex.
 *
 * Works like g_mutex_trylock(), but for a #GStaticMutex.
 *
 * Returns: %TRUE, if the #GStaticMutex could be locked.
 *
 * Deprecated: 2.32: Use g_mutex_trylock()
 */

/**
 * g_static_mutex_unlock:
 * @mutex: a #GStaticMutex.
 *
 * Works like g_mutex_unlock(), but for a #GStaticMutex.
 *
 * Deprecated: 2.32: Use g_mutex_unlock()
 */

/**
 * g_static_mutex_free:
 * @mutex: a #GStaticMutex to be freed.
 *
 * Releases all resources allocated to @mutex.
 *
 * You don't have to call this functions for a #GStaticMutex with an
 * unbounded lifetime, i.e. objects declared 'static', but if you have
 * a #GStaticMutex as a member of a structure and the structure is
 * freed, you should also free the #GStaticMutex.
 *
 * Calling g_static_mutex_free() on a locked mutex may result in
 * undefined behaviour.
 *
 * Deprecated: 2.32: Use g_mutex_clear()
 */
void
g_static_mutex_free (GStaticMutex* mutex)
{
  GMutex **runtime_mutex;

  g_return_if_fail (mutex);

  /* The runtime_mutex is the first (or only) member of GStaticMutex,
   * see both versions (of glibconfig.h) in configure.ac. Note, that
   * this variable is NULL, if g_thread_init() hasn't been called or
   * if we're using the default thread implementation and it provides
   * static mutexes. */
  runtime_mutex = ((GMutex**)mutex);

  if (*runtime_mutex)
    g_mutex_free (*runtime_mutex);

  *runtime_mutex = NULL;
}

/* {{{1 GStaticRecMutex */

/**
 * GStaticRecMutex:
 *
 * A #GStaticRecMutex works like a #GStaticMutex, but it can be locked
 * multiple times by one thread. If you enter it n times, you have to
 * unlock it n times again to let other threads lock it. An exception
 * is the function g_static_rec_mutex_unlock_full(): that allows you to
 * unlock a #GStaticRecMutex completely returning the depth, (i.e. the
 * number of times this mutex was locked). The depth can later be used
 * to restore the state of the #GStaticRecMutex by calling
 * g_static_rec_mutex_lock_full(). In GLib 2.32, #GStaticRecMutex has
 * been deprecated in favor of #GRecMutex.
 *
 * Even though #GStaticRecMutex is not opaque, it should only be used
 * with the following functions.
 *
 * All of the g_static_rec_mutex_* functions can be used even if
 * g_thread_init() has not been called. Then they do nothing, apart
 * from g_static_rec_mutex_trylock(), which does nothing but returning
 * %TRUE.
 */

/**
 * G_STATIC_REC_MUTEX_INIT:
 *
 * A #GStaticRecMutex must be initialized with this macro before it can
 * be used. This macro can used be to initialize a variable, but it
 * cannot be assigned to a variable. In that case you have to use
 * g_static_rec_mutex_init().
 *
 * |[
 *   GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT;
 * ]|
 */

/**
 * g_static_rec_mutex_init:
 * @mutex: a #GStaticRecMutex to be initialized.
 *
 * A #GStaticRecMutex must be initialized with this function before it
 * can be used. Alternatively you can initialize it with
 * #G_STATIC_REC_MUTEX_INIT.
 *
 * Deprecated: 2.32: Use g_rec_mutex_init()
 */
void
g_static_rec_mutex_init (GStaticRecMutex *mutex)
{
  static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;

  g_return_if_fail (mutex);

  *mutex = init_mutex;
}

static GRecMutex *
g_static_rec_mutex_get_rec_mutex_impl (GStaticRecMutex* mutex)
{
  GRecMutex *result;

  if (!g_thread_supported ())
    return NULL;

  result = g_atomic_pointer_get (&mutex->mutex.mutex);

  if (!result)
    {
      G_LOCK (g_static_mutex);

      result = (GRecMutex *) mutex->mutex.mutex;
      if (!result)
        {
          result = g_slice_new (GRecMutex);
          g_rec_mutex_init (result);
          g_atomic_pointer_set (&mutex->mutex.mutex, result);
        }

      G_UNLOCK (g_static_mutex);
    }

  return result;
}

/**
 * g_static_rec_mutex_lock:
 * @mutex: a #GStaticRecMutex to lock.
 *
 * Locks @mutex. If @mutex is already locked by another thread, the
 * current thread will block until @mutex is unlocked by the other
 * thread. If @mutex is already locked by the calling thread, this
 * functions increases the depth of @mutex and returns immediately.
 *
 * Deprecated: 2.32: Use g_rec_mutex_lock()
 */
void
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
{
  GRecMutex *rm;
  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
  g_rec_mutex_lock (rm);
  mutex->depth++;
}

/**
 * g_static_rec_mutex_trylock:
 * @mutex: a #GStaticRecMutex to lock.
 *
 * Tries to lock @mutex. If @mutex is already locked by another thread,
 * it immediately returns %FALSE. Otherwise it locks @mutex and returns
 * %TRUE. If @mutex is already locked by the calling thread, this
 * functions increases the depth of @mutex and immediately returns
 * %TRUE.
 *
 * Returns: %TRUE, if @mutex could be locked.
 *
 * Deprecated: 2.32: Use g_rec_mutex_trylock()
 */
gboolean
g_static_rec_mutex_trylock (GStaticRecMutex* mutex)
{
  GRecMutex *rm;
  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);

  if (g_rec_mutex_trylock (rm))
    {
      mutex->depth++;
      return TRUE;
    }
  else
    return FALSE;
}

/**
 * g_static_rec_mutex_unlock:
 * @mutex: a #GStaticRecMutex to unlock.
 *
 * Unlocks @mutex. Another thread will be allowed to lock @mutex only
 * when it has been unlocked as many times as it had been locked
 * before. If @mutex is completely unlocked and another thread is
 * blocked in a g_static_rec_mutex_lock() call for @mutex, it will be
 * woken and can lock @mutex itself.
 *
 * Deprecated: 2.32: Use g_rec_mutex_unlock()
 */
void
g_static_rec_mutex_unlock (GStaticRecMutex* mutex)
{
  GRecMutex *rm;
  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
  mutex->depth--;
  g_rec_mutex_unlock (rm);
}

/**
 * g_static_rec_mutex_lock_full:
 * @mutex: a #GStaticRecMutex to lock.
 * @depth: number of times this mutex has to be unlocked to be
 *         completely unlocked.
 *
 * Works like calling g_static_rec_mutex_lock() for @mutex @depth times.
 *
 * Deprecated: 2.32: Use g_rec_mutex_lock()
 */
void
g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
                              guint            depth)
{
  GRecMutex *rm;

  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
  while (depth--)
    {
      g_rec_mutex_lock (rm);
      mutex->depth++;
    }
}

/**
 * g_static_rec_mutex_unlock_full:
 * @mutex: a #GStaticRecMutex to completely unlock.
 *
 * Completely unlocks @mutex. If another thread is blocked in a
 * g_static_rec_mutex_lock() call for @mutex, it will be woken and can
 * lock @mutex itself. This function returns the number of times that
 * @mutex has been locked by the current thread. To restore the state
 * before the call to g_static_rec_mutex_unlock_full() you can call
 * g_static_rec_mutex_lock_full() with the depth returned by this
 * function.
 *
 * Returns: number of times @mutex has been locked by the current
 *          thread.
 *
 * Deprecated: 2.32: Use g_rec_mutex_unlock()
 */
guint
g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
{
  GRecMutex *rm;
  gint depth;
  gint i;

  rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);

  /* all access to mutex->depth done while still holding the lock */
  depth = mutex->depth;
  i = mutex->depth;
  mutex->depth = 0;

  while (i--)
    g_rec_mutex_unlock (rm);

  return depth;
}

/**
 * g_static_rec_mutex_free:
 * @mutex: a #GStaticRecMutex to be freed.
 *
 * Releases all resources allocated to a #GStaticRecMutex.
 *
 * You don't have to call this functions for a #GStaticRecMutex with an
 * unbounded lifetime, i.e. objects declared 'static', but if you have
 * a #GStaticRecMutex as a member of a structure and the structure is
 * freed, you should also free the #GStaticRecMutex.
 *
 * Deprecated: 2.32: Use g_rec_mutex_clear()
 */
void
g_static_rec_mutex_free (GStaticRecMutex *mutex)
{
  g_return_if_fail (mutex);

  if (mutex->mutex.mutex)
    {
      GRecMutex *rm = (GRecMutex *) mutex->mutex.mutex;

      g_rec_mutex_clear (rm);
      g_slice_free (GRecMutex, rm);
    }
}

/* GStaticRWLock {{{1 ----------------------------------------------------- */

/**
 * GStaticRWLock:
 *
 * The #GStaticRWLock struct represents a read-write lock. A read-write
 * lock can be used for protecting data that some portions of code only
 * read from, while others also write. In such situations it is
 * desirable that several readers can read at once, whereas of course
 * only one writer may write at a time.
 *
 * Take a look at the following example:
 * |[
 *   GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
 *   GPtrArray *array;
 *
 *   gpointer
 *   my_array_get (guint index)
 *   {
 *     gpointer retval = NULL;
 *
 *     if (!array)
 *       return NULL;
 *
 *     g_static_rw_lock_reader_lock (&rwlock);
 *     if (index < array->len)
 *       retval = g_ptr_array_index (array, index);
 *     g_static_rw_lock_reader_unlock (&rwlock);
 *
 *     return retval;
 *   }
 *
 *   void
 *   my_array_set (guint index, gpointer data)
 *   {
 *     g_static_rw_lock_writer_lock (&rwlock);
 *
 *     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_static_rw_lock_writer_unlock (&rwlock);
 *   }
 * ]|
 *
 * This example shows an array which can be accessed by many readers
 * (the my_array_get() function) simultaneously, whereas the writers
 * (the my_array_set() 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.
 *
 * Most of the time, writers should have precedence over readers. That
 * means, for this implementation, that as soon as a writer wants to
 * lock the data, no other reader is allowed to lock the data, whereas,
 * of course, the readers that already have locked the data are allowed
 * to finish their operation. As soon as the last reader unlocks the
 * data, the writer will lock it.
 *
 * Even though #GStaticRWLock is not opaque, it should only be used
 * with the following functions.
 *
 * All of the g_static_rw_lock_* functions can be used even if
 * g_thread_init() has not been called. Then they do nothing, apart
 * from g_static_rw_lock_*_trylock, which does nothing but returning %TRUE.
 *
 * A read-write lock has a higher overhead than a mutex. For example, both
 * g_static_rw_lock_reader_lock() and g_static_rw_lock_reader_unlock() have
 * to lock and unlock a #GStaticMutex, so it takes at least twice the time
 * to lock and unlock a #GStaticRWLock that it does to lock and unlock a
 * #GStaticMutex. So only data structures that are accessed by multiple
 * readers, and which keep the lock for a considerable time justify a
 * #GStaticRWLock. The above example most probably would fare better with a
 * #GStaticMutex.
 *
 * Deprecated: 2.32: Use a #GRWLock instead
 **/

/**
 * G_STATIC_RW_LOCK_INIT:
 *
 * A #GStaticRWLock must be initialized with this macro before it can
 * be used. This macro can used be to initialize a variable, but it
 * cannot be assigned to a variable. In that case you have to use
 * g_static_rw_lock_init().
 *
 * |[
 *   GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT;
 * ]|
 */

/**
 * g_static_rw_lock_init:
 * @lock: a #GStaticRWLock to be initialized.
 *
 * A #GStaticRWLock must be initialized with this function before it
 * can be used. Alternatively you can initialize it with
 * #G_STATIC_RW_LOCK_INIT.
 *
 * Deprecated: 2.32: Use g_rw_lock_init() instead
 */
void
g_static_rw_lock_init (GStaticRWLock* lock)
{
  static const GStaticRWLock init_lock = G_STATIC_RW_LOCK_INIT;

  g_return_if_fail (lock);

  *lock = init_lock;
}

inline static void
g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex)
{
  if (!*cond)
      *cond = g_cond_new ();
  g_cond_wait (*cond, g_static_mutex_get_mutex (mutex));
}

inline static void
g_static_rw_lock_signal (GStaticRWLock* lock)
{
  if (lock->want_to_write && lock->write_cond)
    g_cond_signal (lock->write_cond);
  else if (lock->want_to_read && lock->read_cond)
    g_cond_broadcast (lock->read_cond);
}

/**
 * g_static_rw_lock_reader_lock:
 * @lock: a #GStaticRWLock to lock for reading.
 *
 * Locks @lock for reading. There may be unlimited concurrent locks for
 * reading of a #GStaticRWLock at the same time.  If @lock is already
 * locked for writing by another thread or if another thread is already
 * waiting to lock @lock for writing, this function will block until
 * @lock is unlocked by the other writing thread and no other writing
 * threads want to lock @lock. This lock has to be unlocked by
 * g_static_rw_lock_reader_unlock().
 *
 * #GStaticRWLock is not recursive. It might seem to be possible to
 * recursively lock for reading, but that can result in a deadlock, due
 * to writer preference.
 *
 * Deprecated: 2.32: Use g_rw_lock_reader_lock() instead
 */
void
g_static_rw_lock_reader_lock (GStaticRWLock* lock)
{
  g_return_if_fail (lock);

  if (!g_threads_got_initialized)
    return;

  g_static_mutex_lock (&lock->mutex);
  lock->want_to_read++;
  while (lock->have_writer || lock->want_to_write)
    g_static_rw_lock_wait (&lock->read_cond, &lock->mutex);
  lock->want_to_read--;
  lock->read_counter++;
  g_static_mutex_unlock (&lock->mutex);
}

/**
 * g_static_rw_lock_reader_trylock:
 * @lock: a #GStaticRWLock to lock for reading
 *
 * Tries to lock @lock for reading. If @lock is already locked for
 * writing by another thread or if another thread is already waiting to
 * lock @lock for writing, immediately returns %FALSE. Otherwise locks
 * @lock for reading and returns %TRUE. This lock has to be unlocked by
 * g_static_rw_lock_reader_unlock().
 *
 * Returns: %TRUE, if @lock could be locked for reading
 *
 * Deprectated: 2.32: Use g_rw_lock_reader_trylock() instead
 */
gboolean
g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
{
  gboolean ret_val = FALSE;

  g_return_val_if_fail (lock, FALSE);

  if (!g_threads_got_initialized)
    return TRUE;

  g_static_mutex_lock (&lock->mutex);
  if (!lock->have_writer && !lock->want_to_write)
    {
      lock->read_counter++;
      ret_val = TRUE;
    }
  g_static_mutex_unlock (&lock->mutex);
  return ret_val;
}

/**
 * g_static_rw_lock_reader_unlock:
 * @lock: a #GStaticRWLock to unlock after reading
 *
 * Unlocks @lock. If a thread waits to lock @lock for writing and all
 * locks for reading have been unlocked, the waiting thread is woken up
 * and can lock @lock for writing.
 *
 * Deprectated: 2.32: Use g_rw_lock_reader_unlock() instead
 */
void
g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
{
  g_return_if_fail (lock);

  if (!g_threads_got_initialized)
    return;

  g_static_mutex_lock (&lock->mutex);
  lock->read_counter--;
  if (lock->read_counter == 0)
    g_static_rw_lock_signal (lock);
  g_static_mutex_unlock (&lock->mutex);
}

/**
 * g_static_rw_lock_writer_lock:
 * @lock: a #GStaticRWLock to lock for writing
 *
 * Locks @lock for writing. If @lock is already locked for writing or
 * reading by other threads, this function will block until @lock is
 * completely unlocked and then lock @lock for writing. While this
 * functions waits to lock @lock, no other thread can lock @lock for
 * reading. When @lock is locked for writing, no other thread can lock
 * @lock (neither for reading nor writing). This lock has to be
 * unlocked by g_static_rw_lock_writer_unlock().
 *
 * Deprectated: 2.32: Use g_rw_lock_writer_lock() instead
 */
void
g_static_rw_lock_writer_lock (GStaticRWLock* lock)
{
  g_return_if_fail (lock);

  if (!g_threads_got_initialized)
    return;

  g_static_mutex_lock (&lock->mutex);
  lock->want_to_write++;
  while (lock->have_writer || lock->read_counter)
    g_static_rw_lock_wait (&lock->write_cond, &lock->mutex);
  lock->want_to_write--;
  lock->have_writer = TRUE;
  g_static_mutex_unlock (&lock->mutex);
}

/**
 * g_static_rw_lock_writer_trylock:
 * @lock: a #GStaticRWLock to lock for writing
 *
 * Tries to lock @lock for writing. If @lock is already locked (for
 * either reading or writing) by another thread, it immediately returns
 * %FALSE. Otherwise it locks @lock for writing and returns %TRUE. This
 * lock has to be unlocked by g_static_rw_lock_writer_unlock().
 *
 * Returns: %TRUE, if @lock could be locked for writing
 *
 * Deprectated: 2.32: Use g_rw_lock_writer_trylock() instead
 */
gboolean
g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
{
  gboolean ret_val = FALSE;

  g_return_val_if_fail (lock, FALSE);

  if (!g_threads_got_initialized)
    return TRUE;

  g_static_mutex_lock (&lock->mutex);
  if (!lock->have_writer && !lock->read_counter)
    {
      lock->have_writer = TRUE;
      ret_val = TRUE;
    }
  g_static_mutex_unlock (&lock->mutex);
  return ret_val;
}

/**
 * g_static_rw_lock_writer_unlock:
 * @lock: a #GStaticRWLock to unlock after writing.
 *
 * Unlocks @lock. If a thread is waiting to lock @lock for writing and
 * all locks for reading have been unlocked, the waiting thread is
 * woken up and can lock @lock for writing. If no thread is waiting to
 * lock @lock for writing, and some thread or threads are waiting to
 * lock @lock for reading, the waiting threads are woken up and can
 * lock @lock for reading.
 *
 * Deprectated: 2.32: Use g_rw_lock_writer_unlock() instead
 */
void
g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
{
  g_return_if_fail (lock);

  if (!g_threads_got_initialized)
    return;

  g_static_mutex_lock (&lock->mutex);
  lock->have_writer = FALSE;
  g_static_rw_lock_signal (lock);
  g_static_mutex_unlock (&lock->mutex);
}

/**
 * g_static_rw_lock_free:
 * @lock: a #GStaticRWLock to be freed.
 *
 * Releases all resources allocated to @lock.
 *
 * You don't have to call this functions for a #GStaticRWLock with an
 * unbounded lifetime, i.e. objects declared 'static', but if you have
 * a #GStaticRWLock as a member of a structure, and the structure is
 * freed, you should also free the #GStaticRWLock.
 *
 * Deprecated: 2.32: Use a #GRWLock instead
 */
void
g_static_rw_lock_free (GStaticRWLock* lock)
{
  g_return_if_fail (lock);

  if (lock->read_cond)
    {
      g_cond_free (lock->read_cond);
      lock->read_cond = NULL;
    }
  if (lock->write_cond)
    {
      g_cond_free (lock->write_cond);
      lock->write_cond = NULL;
    }
  g_static_mutex_free (&lock->mutex);
}

/* GPrivate {{{1 ------------------------------------------------------ */

/**
 * g_private_new:
 * @notify: a #GDestroyNotify
 *
 * Creates a new #GPrivate.
 *
 * Deprecated:2.32: dynamic allocation of #GPrivate is a bad idea.  Use
 *                  static storage and G_PRIVATE_INIT() instead.
 *
 * Returns: a newly allocated #GPrivate (which can never be destroyed)
 */
GPrivate *
g_private_new (GDestroyNotify notify)
{
  GPrivate tmp = G_PRIVATE_INIT (notify);
  GPrivate *key;

  key = g_slice_new (GPrivate);
  *key = tmp;

  return key;
}

/* {{{1 GStaticPrivate */

typedef struct _GStaticPrivateNode GStaticPrivateNode;
struct _GStaticPrivateNode
{
  gpointer        data;
  GDestroyNotify  destroy;
  GStaticPrivate *owner;
};

static void
g_static_private_cleanup (gpointer data)
{
  GArray *array = data;
  guint i;

  for (i = 0; i < array->len; i++ )
    {
      GStaticPrivateNode *node = &g_array_index (array, GStaticPrivateNode, i);
      if (node->destroy)
        node->destroy (node->data);
    }

  g_array_free (array, TRUE);
}

GPrivate static_private_private = G_PRIVATE_INIT (g_static_private_cleanup);

/**
 * GStaticPrivate:
 *
 * A #GStaticPrivate works almost like a #GPrivate, but it has one
 * significant advantage. It doesn't need to be created at run-time
 * like a #GPrivate, but can be defined at compile-time. This is
 * similar to the difference between #GMutex and #GStaticMutex.
 *
 * Now look at our give_me_next_number() example with #GStaticPrivate:
 * |[
 *   int
 *   give_me_next_number ()
 *   {
 *     static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT;
 *     int *current_number = g_static_private_get (&current_number_key);
 *
 *     if (!current_number)
 *       {
 *         current_number = g_new (int, 1);
 *         *current_number = 0;
 *         g_static_private_set (&current_number_key, current_number, g_free);
 *       }
 *
 *     *current_number = calc_next_number (*current_number);
 *
 *     return *current_number;
 *   }
 * ]|
 */

/**
 * G_STATIC_PRIVATE_INIT:
 *
 * Every #GStaticPrivate must be initialized with this macro, before it
 * can be used.
 *
 * |[
 *   GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;
 * ]|
 */

/**
 * g_static_private_init:
 * @private_key: a #GStaticPrivate to be initialized
 *
 * Initializes @private_key. Alternatively you can initialize it with
 * #G_STATIC_PRIVATE_INIT.
 */
void
g_static_private_init (GStaticPrivate *private_key)
{
  private_key->index = 0;
}

/**
 * g_static_private_get:
 * @private_key: a #GStaticPrivate
 *
 * Works like g_private_get() only for a #GStaticPrivate.
 *
 * This function works even if g_thread_init() has not yet been called.
 *
 * Returns: the corresponding pointer
 */
gpointer
g_static_private_get (GStaticPrivate *private_key)
{
  GArray *array;
  gpointer ret = NULL;

  array = g_private_get (&static_private_private);

  if (array && private_key->index != 0 && private_key->index <= array->len)
    {
      GStaticPrivateNode *node;

      node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1);

      /* Deal with the possibility that the GStaticPrivate which used
       * to have this index got freed and the index got allocated to
       * a new one. In this case, the data in the node is stale, so
       * free it and return NULL.
       */
      if (G_UNLIKELY (node->owner != private_key))
        {
          if (node->destroy)
            node->destroy (node->data);
          node->destroy = NULL;
          node->data = NULL;
          node->owner = NULL;
        }
      ret = node->data;
    }

  return ret;
}

/**
 * g_static_private_set:
 * @private_key: a #GStaticPrivate
 * @data: the new pointer
 * @notify: a function to be called with the pointer whenever the
 *     current thread ends or sets this pointer again
 *
 * Sets the pointer keyed to @private_key for the current thread and
 * the function @notify to be called with that pointer (%NULL or
 * non-%NULL), whenever the pointer is set again or whenever the
 * current thread ends.
 *
 * This function works even if g_thread_init() has not yet been called.
 * If g_thread_init() is called later, the @data keyed to @private_key
 * will be inherited only by the main thread, i.e. the one that called
 * g_thread_init().
 *
 * @notify is used quite differently from @destructor in g_private_new().
 */
void
g_static_private_set (GStaticPrivate *private_key,
                      gpointer        data,
                      GDestroyNotify  notify)
{
  GArray *array;
  static guint next_index = 0;
  GStaticPrivateNode *node;

  if (!private_key->index)
    {
      G_LOCK (g_thread);

      if (!private_key->index)
        {
          if (g_thread_free_indices)
            {
              private_key->index = GPOINTER_TO_UINT (g_thread_free_indices->data);
              g_thread_free_indices = g_slist_delete_link (g_thread_free_indices,
                                                           g_thread_free_indices);
            }
          else
            private_key->index = ++next_index;
        }

      G_UNLOCK (g_thread);
    }

  array = g_private_get (&static_private_private);
  if (!array)
    {
      array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode));
      g_private_set (&static_private_private, array);
    }
  if (private_key->index > array->len)
    g_array_set_size (array, private_key->index);

  node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1);

  if (node->destroy)
    node->destroy (node->data);

  node->data = data;
  node->destroy = notify;
  node->owner = private_key;
}

/**
 * g_static_private_free:
 * @private_key: a #GStaticPrivate to be freed
 *
 * Releases all resources allocated to @private_key.
 *
 * You don't have to call this functions for a #GStaticPrivate with an
 * unbounded lifetime, i.e. objects declared 'static', but if you have
 * a #GStaticPrivate as a member of a structure and the structure is
 * freed, you should also free the #GStaticPrivate.
 */
void
g_static_private_free (GStaticPrivate *private_key)
{
  guint idx = private_key->index;

  if (!idx)
    return;

  private_key->index = 0;

  /* Freeing the per-thread data is deferred to either the
   * thread end or the next g_static_private_get() call for
   * the same index.
   */
  G_LOCK (g_thread);
  g_thread_free_indices = g_slist_prepend (g_thread_free_indices,
                                           GUINT_TO_POINTER (idx));
  G_UNLOCK (g_thread);
}

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

/**
 * g_mutex_new:
 *
 * Allocates and initializes a new #GMutex.
 *
 * Returns: a newly allocated #GMutex. Use g_mutex_free() to free
 *
 * Deprecated: 2.32: GMutex can now be statically allocated, or embedded
 * in structures and initialised with g_mutex_init().
 */
GMutex *
g_mutex_new (void)
{
  GMutex *mutex;

  mutex = g_slice_new (GMutex);
  g_mutex_init (mutex);

  return mutex;
}

/**
 * g_mutex_free:
 * @mutex: a #GMutex
 *
 * Destroys a @mutex that has been created with g_mutex_new().
 *
 * Calling g_mutex_free() on a locked mutex may result
 * in undefined behaviour.
 *
 * Deprecated: 2.32: GMutex can now be statically allocated, or embedded
 * in structures and initialised with g_mutex_init().
 */
void
g_mutex_free (GMutex *mutex)
{
  g_mutex_clear (mutex);
  g_slice_free (GMutex, mutex);
}

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

/**
 * g_cond_new:
 *
 * Allocates and initializes a new #GCond.
 *
 * Returns: a newly allocated #GCond. Free with g_cond_free()
 *
 * Deprecated: 2.32: GCond can now be statically allocated, or embedded
 * in structures and initialised with g_cond_init().
 */
GCond *
g_cond_new (void)
{
  GCond *cond;

  cond = g_slice_new (GCond);
  g_cond_init (cond);

  return cond;
}

/**
 * g_cond_free:
 * @cond: a #GCond
 *
 * Destroys a #GCond that has been created with g_cond_new().
 *
 * Calling g_cond_free() for a #GCond on which threads are
 * blocking leads to undefined behaviour.
 *
 * Deprecated: 2.32: GCond can now be statically allocated, or embedded
 * in structures and initialised with g_cond_init().
 */
void
g_cond_free (GCond *cond)
{
  g_cond_clear (cond);
  g_slice_free (GCond, cond);
}

/**
 * g_cond_timed_wait:
 * @cond: a #GCond
 * @mutex: a #GMutex that is currently locked
 * @abs_time: a #GTimeVal, determining the final time
 *
 * Waits until this thread is woken up on @cond, but not longer than
 * until the time specified by @abs_time. The @mutex is unlocked before
 * falling asleep and locked again before resuming.
 *
 * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
 *
 * This function can be used even if g_thread_init() has not yet been
 * called, and, in that case, will immediately return %TRUE.
 *
 * To easily calculate @abs_time a combination of g_get_current_time()
 * and g_time_val_add() can be used.
 *
 * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
 *
 * Deprecated:2.32: Use g_cond_wait_until() instead.
 */
gboolean
g_cond_timed_wait (GCond    *cond,
                   GMutex   *mutex,
                   GTimeVal *abs_time)
{
  gint64 end_time;

  if (abs_time == NULL)
    {
      g_cond_wait (cond, mutex);
      return TRUE;
    }

  end_time = abs_time->tv_sec;
  end_time *= 1000000;
  end_time += abs_time->tv_usec;

  /* would be nice if we had clock_rtoffset, but that didn't seem to
   * make it into the kernel yet...
   */
  end_time += g_get_monotonic_time () - g_get_real_time ();

  return g_cond_wait_until (cond, mutex, end_time);
}

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