/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * gmutex.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 Library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 */

/* 
 * MT safe
 */

#include "glib.h"

typedef struct _GStaticPrivateNode GStaticPrivateNode;

struct _GStaticPrivateNode
{
  gpointer       data;
  GDestroyNotify destroy;
};

static void g_static_private_free_data (gpointer data);
static void g_thread_fail (void);

/* Global variables */

gboolean g_thread_use_default_impl = TRUE;
gboolean g_threads_got_initialized = FALSE;

GThreadFunctions g_thread_functions_for_glib_use = {
  (GMutex*(*)())g_thread_fail,                 /* mutex_new */
  NULL,                                        /* mutex_lock */
  NULL,                                        /* mutex_trylock */
  NULL,                                        /* mutex_unlock */
  NULL,                                        /* mutex_free */
  (GCond*(*)())g_thread_fail,                  /* cond_new */
  NULL,                                        /* cond_signal */
  NULL,                                        /* cond_broadcast */
  NULL,                                        /* cond_wait */
  NULL,                                        /* cond_timed_wait  */
  NULL,                                        /* cond_free */
  (GPrivate*(*)(GDestroyNotify))g_thread_fail, /* private_new */
  NULL,                                        /* private_get */
  NULL,                                        /* private_set */
}; 

/* Local data */

static GMutex   *g_mutex_protect_static_mutex_allocation = NULL;
static GMutex   *g_thread_specific_mutex = NULL;
static GPrivate *g_thread_specific_private = NULL;

/* This must be called only once, before any threads are created.
 * It will only be called from g_thread_init() in -lgthread.
 */
void
g_mutex_init (void)
{
  /* We let the main thread (the one that calls g_thread_init) inherit
   * the data, that it set before calling g_thread_init
   */
  gpointer private_old = g_thread_specific_private;

  g_thread_specific_private = g_private_new (g_static_private_free_data);

  /* we can not use g_private_set here, as g_threads_got_initialized is not
   * yet set TRUE, whereas the private_set function is already set.
   */
  g_thread_functions_for_glib_use.private_set (g_thread_specific_private, 
					       private_old);

  g_mutex_protect_static_mutex_allocation = g_mutex_new();
  g_thread_specific_mutex = g_mutex_new();
}

GMutex *
g_static_mutex_get_mutex_impl (GMutex** mutex)
{
  if (!g_thread_supported ())
    return NULL;

  g_assert (g_mutex_protect_static_mutex_allocation);

  g_mutex_lock (g_mutex_protect_static_mutex_allocation);

  if (!(*mutex)) 
    *mutex = g_mutex_new(); 

  g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
  
  return *mutex;
}

gpointer
g_static_private_get (GStaticPrivate *private_key)
{
  GArray *array;

  array = g_private_get (g_thread_specific_private);
  if (!array)
    return NULL;

  if (!private_key->index)
    return NULL;
  else if (private_key->index <= array->len)
    return g_array_index (array, GStaticPrivateNode, private_key->index - 1).data;
  else
    return NULL;
}

void
g_static_private_set (GStaticPrivate *private_key, 
		      gpointer        data,
		      GDestroyNotify  notify)
{
  GArray *array;
  static guint next_index = 0;
  GStaticPrivateNode *node;
  
  array = g_private_get (g_thread_specific_private);
  if (!array)
    {
      array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode));
      g_private_set (g_thread_specific_private, array);
    }

  if (!private_key->index)
    {
      g_mutex_lock (g_thread_specific_mutex);

      if (!private_key->index)
	private_key->index = ++next_index;

      g_mutex_unlock (g_thread_specific_mutex);
    }

  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)
    {
      gpointer ddata = node->data;
      GDestroyNotify ddestroy = node->destroy;

      node->data = data;
      node->destroy = notify;

      ddestroy (ddata);
    }
  else
    {
      node->data = data;
      node->destroy = notify;
    }
}

static void
g_static_private_free_data (gpointer data)
{
  if (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);
	}
    }
}

static void
g_thread_fail (void)
{
  g_error ("The thread system is not yet initialized.");
}
