/* 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.1 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 */
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif

#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, NULL, 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 these 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 = (GRecMutex *) 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, (GMutex *) 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
 *
 * Deprecated: 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.
 *
 * Deprecated: 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().
 *
 * Deprecated: 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
 *
 * Deprecated: 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.
 *
 * Deprecated: 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_real_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: */
