/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * gthread.c: thread related functions
 * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
 *
 * 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.
 */

/*
 * 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
 */

#include "config.h"

#include "glib.h"
#include "gthreadprivate.h"

#ifdef G_THREADS_ENABLED

static GSystemThread zero_thread; /* This is initialized to all zero */
static gboolean thread_system_already_initialized = FALSE;
static gint g_thread_priority_map [G_THREAD_PRIORITY_URGENT + 1];

#include G_THREAD_SOURCE

#ifndef PRIORITY_LOW_VALUE
# define PRIORITY_LOW_VALUE 0
#endif

#ifndef PRIORITY_URGENT_VALUE
# define PRIORITY_URGENT_VALUE 0
#endif

#ifndef PRIORITY_NORMAL_VALUE
# define PRIORITY_NORMAL_VALUE						\
  ((PRIORITY_LOW_VALUE * 6 + PRIORITY_URGENT_VALUE * 4) / 10)
#endif /* PRIORITY_NORMAL_VALUE */

#ifndef PRIORITY_HIGH_VALUE
# define PRIORITY_HIGH_VALUE						\
  ((PRIORITY_NORMAL_VALUE + PRIORITY_URGENT_VALUE * 2) / 3)
#endif /* PRIORITY_HIGH_VALUE */

void g_mutex_init (void);
void g_mem_init (void);
void g_messages_init (void);
void g_convert_init (void);
void g_rand_init (void);
void g_main_thread_init (void);

typedef struct _GMutexDebugInfo GMutexDebugInfo;
struct _GMutexDebugInfo
{
  gchar *location;
  GSystemThread owner;
};

#define G_MUTEX_DEBUG_INFO(mutex) 					\
  (((GMutexDebugInfo*)(((char*)mutex)+G_MUTEX_SIZE)))

static GMutex *
g_mutex_new_errorcheck_impl (void)
{
  GMutex *retval = g_thread_functions_for_glib_use_default.mutex_new ();
  GMutexDebugInfo *info;
  retval = g_realloc (retval, G_MUTEX_SIZE + sizeof (GMutexDebugInfo));

  info = G_MUTEX_DEBUG_INFO (retval);
  g_system_thread_assign (info->owner, zero_thread);
  info->location = "invalid";

  return retval;
}

static void
g_mutex_lock_errorcheck_impl (GMutex *mutex,
			      const gulong magic,
			      gchar * const location)
{
  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";

  GSystemThread self;
  g_thread_functions_for_glib_use.thread_self (&self);

  if (g_system_thread_equal (info->owner, self))
    g_error ("Trying to recursivly lock a mutex at '%s', "
	     "previously locked at '%s'",
	     loc, info->location);

  g_thread_functions_for_glib_use_default.mutex_lock (mutex);

  g_system_thread_assign (info->owner, self);
  info->location = loc;
}

static gboolean
g_mutex_trylock_errorcheck_impl (GMutex *mutex,
				 const gulong magic,
				 gchar * const location)
{
  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";

  GSystemThread self;
  g_thread_functions_for_glib_use.thread_self (&self);

  if (g_system_thread_equal (info->owner, self))
    g_error ("Trying to recursivly lock a mutex at '%s', "
	     "previously locked at '%s'",
	     loc, info->location);

  if (!g_thread_functions_for_glib_use_default.mutex_trylock (mutex))
    return FALSE;

  g_system_thread_assign (info->owner, self);
  info->location = loc;

  return TRUE;
}

static void
g_mutex_unlock_errorcheck_impl (GMutex *mutex,
				const gulong magic,
				gchar * const location)
{
  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";

  GSystemThread self;
  g_thread_functions_for_glib_use.thread_self (&self);

  if (g_system_thread_equal (info->owner, zero_thread))
    g_error ("Trying to unlock an unlocked mutex at '%s'", loc);

  if (!g_system_thread_equal (info->owner, self))
    g_warning ("Trying to unlock a mutex at '%s', "
	       "previously locked by a different thread at '%s'",
	       loc, info->location);

  g_system_thread_assign (info->owner, zero_thread);
  info->location = NULL;

  g_thread_functions_for_glib_use_default.mutex_unlock (mutex);
}

static void
g_mutex_free_errorcheck_impl (GMutex *mutex,
			      const gulong magic,
			      gchar * const location)
{
  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";

  if (info && !g_system_thread_equal (info->owner, zero_thread))
    g_error ("Trying to free a locked mutex at '%s', "
	     "which was previously locked at '%s'",
	     loc, info->location);

  g_thread_functions_for_glib_use_default.mutex_free (mutex);
}

static void
g_cond_wait_errorcheck_impl (GCond *cond,
			     GMutex *mutex,
			     const gulong magic,
			     gchar * const location)
{
  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";

  GSystemThread self;
  g_thread_functions_for_glib_use.thread_self (&self);

  if (g_system_thread_equal (info->owner, zero_thread))
    g_error ("Trying to use an unlocked mutex in g_cond_wait() at '%s'", loc);

  if (!g_system_thread_equal (info->owner, self))
    g_error ("Trying to use a mutex locked by another thread in "
	     "g_cond_wait() at '%s'", loc);

  g_system_thread_assign (info->owner, zero_thread);
  loc = info->location;

  g_thread_functions_for_glib_use_default.cond_wait (cond, mutex);

  g_system_thread_assign (info->owner, self);
  info->location = loc;
}


static gboolean
g_cond_timed_wait_errorcheck_impl (GCond *cond,
                                   GMutex *mutex,
                                   GTimeVal *end_time,
				   const gulong magic,
				   gchar * const location)
{
  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";
  gboolean retval;

  GSystemThread self;
  g_thread_functions_for_glib_use.thread_self (&self);

  if (g_system_thread_equal (info->owner, zero_thread))
    g_error ("Trying to use an unlocked mutex in g_cond_timed_wait() at '%s'",
	     loc);

  if (!g_system_thread_equal (info->owner, self))
    g_error ("Trying to use a mutex locked by another thread in "
	     "g_cond_timed_wait() at '%s'", loc);

  g_system_thread_assign (info->owner, zero_thread);
  loc = info->location;

  retval = g_thread_functions_for_glib_use_default.cond_timed_wait (cond,
								    mutex,
								    end_time);

  g_system_thread_assign (info->owner, self);
  info->location = loc;

  return retval;
}


/* unshadow function declaration. See gthread.h */
#undef g_thread_init

void
g_thread_init_with_errorcheck_mutexes (GThreadFunctions* init)
{
  GThreadFunctions errorcheck_functions;
  if (init)
    g_error ("Errorcheck mutexes can only be used for native "
	     "thread implementations. Sorry." );

#ifdef HAVE_G_THREAD_IMPL_INIT
  /* This isn't called in g_thread_init, as it doesn't think to get
   * the default implementation, so we have to call it on our own.
   *
   * We must call this before copying
   * g_thread_functions_for_glib_use_default as the
   * implementation-specific init function might modify the contents
   * of g_thread_functions_for_glib_use_default based on operating
   * system version, C library version, or whatever. */
  g_thread_impl_init();
#endif /* HAVE_G_THREAD_IMPL_INIT */

  errorcheck_functions = g_thread_functions_for_glib_use_default;
  errorcheck_functions.mutex_new = g_mutex_new_errorcheck_impl;
  errorcheck_functions.mutex_lock =
    (void (*)(GMutex *)) g_mutex_lock_errorcheck_impl;
  errorcheck_functions.mutex_trylock =
    (gboolean (*)(GMutex *)) g_mutex_trylock_errorcheck_impl;
  errorcheck_functions.mutex_unlock =
    (void (*)(GMutex *)) g_mutex_unlock_errorcheck_impl;
  errorcheck_functions.mutex_free =
    (void (*)(GMutex *)) g_mutex_free_errorcheck_impl;
  errorcheck_functions.cond_wait =
    (void (*)(GCond *, GMutex *)) g_cond_wait_errorcheck_impl;
  errorcheck_functions.cond_timed_wait =
    (gboolean (*)(GCond *, GMutex *, GTimeVal *))
    g_cond_timed_wait_errorcheck_impl;

  g_thread_init (&errorcheck_functions);
}

void
g_thread_init (GThreadFunctions* init)
{
  gboolean supported;

  if (thread_system_already_initialized)
    g_error ("GThread system may only be initialized once.");

  thread_system_already_initialized = TRUE;

  if (init == NULL)
    {
#ifdef HAVE_G_THREAD_IMPL_INIT
      /* now do any initialization stuff required by the
       * implementation, but only if called with a NULL argument, of
       * course. Otherwise it's up to the user to do so. */
      g_thread_impl_init();
#endif /* HAVE_G_THREAD_IMPL_INIT */
      init = &g_thread_functions_for_glib_use_default;
    }
  else
    g_thread_use_default_impl = FALSE;

  g_thread_functions_for_glib_use = *init;
  if (g_thread_gettime_impl)
    g_thread_gettime = g_thread_gettime_impl;

  supported = (init->mutex_new &&
	       init->mutex_lock &&
	       init->mutex_trylock &&
	       init->mutex_unlock &&
	       init->mutex_free &&
	       init->cond_new &&
	       init->cond_signal &&
	       init->cond_broadcast &&
	       init->cond_wait &&
	       init->cond_timed_wait &&
	       init->cond_free &&
	       init->private_new &&
	       init->private_get &&
	       init->private_set &&
	       init->thread_create &&
	       init->thread_yield &&
	       init->thread_join &&
	       init->thread_exit &&
	       init->thread_set_priority &&
	       init->thread_self);

  /* if somebody is calling g_thread_init (), it means that he wants to
   * have thread support, so check this
   */
  if (!supported)
    {
      if (g_thread_use_default_impl)
	g_error ("Threads are not supported on this platform.");
      else
	g_error ("The supplied thread function vector is invalid.");
    }

  g_thread_priority_map [G_THREAD_PRIORITY_LOW] = PRIORITY_LOW_VALUE;
  g_thread_priority_map [G_THREAD_PRIORITY_NORMAL] = PRIORITY_NORMAL_VALUE;
  g_thread_priority_map [G_THREAD_PRIORITY_HIGH] = PRIORITY_HIGH_VALUE;
  g_thread_priority_map [G_THREAD_PRIORITY_URGENT] = PRIORITY_URGENT_VALUE;

  g_thread_init_glib ();
}

#else /* !G_THREADS_ENABLED */

void
g_thread_init (GThreadFunctions* init)
{
  g_error ("GLib thread support is disabled.");
}

#endif /* !G_THREADS_ENABLED */
