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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <glib.h>

#define STRICT
#define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */
#include <windows.h>
#undef STRICT

#include <process.h>
#include <stdlib.h>
#include <stdio.h>

#define win32_check_for_error(what) G_STMT_START{			\
  if (!(what))								\
    g_error ("file %s: line %d (%s): error %s during %s",		\
	     __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,		\
	     g_win32_error_message (GetLastError ()), #what);		\
  }G_STMT_END

#define G_MUTEX_SIZE (sizeof (gpointer))

#define PRIORITY_LOW_VALUE    THREAD_PRIORITY_BELOW_NORMAL
#define PRIORITY_NORMAL_VALUE THREAD_PRIORITY_NORMAL
#define PRIORITY_HIGH_VALUE   THREAD_PRIORITY_ABOVE_NORMAL
#define PRIORITY_URGENT_VALUE THREAD_PRIORITY_HIGHEST

static DWORD g_thread_self_tls;
static DWORD g_private_tls;
static DWORD g_cond_event_tls;
static CRITICAL_SECTION g_thread_global_spinlock;

typedef BOOL (__stdcall *GTryEnterCriticalSectionFunc) (CRITICAL_SECTION *);

static GTryEnterCriticalSectionFunc try_enter_critical_section = NULL;

/* As noted in the docs, GPrivate is a limited resource, here we take
 * a rather low maximum to save memory, use GStaticPrivate instead. */
#define G_PRIVATE_MAX 100

static GDestroyNotify g_private_destructors[G_PRIVATE_MAX];

static guint g_private_next = 0;

typedef struct _GThreadData GThreadData;
struct _GThreadData
{
  GThreadFunc func;
  gpointer data;
  HANDLE thread;
  gboolean joinable;
};

struct _GCond 
{
  GPtrArray *array;
  CRITICAL_SECTION lock;
};

static GMutex *
g_mutex_new_win32_cs_impl (void)
{
  CRITICAL_SECTION *cs = g_new (CRITICAL_SECTION, 1);
  gpointer *retval = g_new (gpointer, 1);

  InitializeCriticalSection (cs);
  *retval = cs;
  return (GMutex *) retval;
}

static void
g_mutex_free_win32_cs_impl (GMutex *mutex)
{
  gpointer *ptr = (gpointer *) mutex;
  CRITICAL_SECTION *cs = (CRITICAL_SECTION *) *ptr;

  DeleteCriticalSection (cs);
  g_free (cs);
  g_free (mutex);
}

/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
   functions from gmem.c and gmessages.c; */

static void
g_mutex_lock_win32_cs_impl (GMutex *mutex)
{
  EnterCriticalSection (*(CRITICAL_SECTION **)mutex);
}

static gboolean
g_mutex_trylock_win32_cs_impl (GMutex * mutex)
{
  return try_enter_critical_section (*(CRITICAL_SECTION **)mutex);
}

static void
g_mutex_unlock_win32_cs_impl (GMutex *mutex)
{
  LeaveCriticalSection (*(CRITICAL_SECTION **)mutex);
}

static GMutex *
g_mutex_new_win32_impl (void)
{
  HANDLE handle;
  HANDLE *retval;
  win32_check_for_error (handle = CreateMutex (NULL, FALSE, NULL));
  retval = g_new (HANDLE, 1);
  *retval = handle;
  return (GMutex *) retval;
}

static void
g_mutex_free_win32_impl (GMutex *mutex)
{
  win32_check_for_error (CloseHandle (*(HANDLE *) mutex));
  g_free (mutex);
}

/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
   functions from gmem.c and gmessages.c; */

static void
g_mutex_lock_win32_impl (GMutex *mutex)
{
  WaitForSingleObject (*(HANDLE *) mutex, INFINITE);
}

static gboolean
g_mutex_trylock_win32_impl (GMutex * mutex)
{
  DWORD result;
  win32_check_for_error (WAIT_FAILED != 
			 (result = WaitForSingleObject (*(HANDLE *)mutex, 0)));
  return result != WAIT_TIMEOUT;
}

static void
g_mutex_unlock_win32_impl (GMutex *mutex)
{
  ReleaseMutex (*(HANDLE *) mutex);
}

static GCond *
g_cond_new_win32_impl (void)
{
  GCond *retval = g_new (GCond, 1);

  retval->array = g_ptr_array_new ();
  InitializeCriticalSection (&retval->lock);

  return retval;
}

static void
g_cond_signal_win32_impl (GCond * cond)
{
  EnterCriticalSection (&cond->lock);

  if (cond->array->len > 0)
    {
      SetEvent (g_ptr_array_index (cond->array, 0));
      g_ptr_array_remove_index (cond->array, 0);
    }

  LeaveCriticalSection (&cond->lock);
}

static void
g_cond_broadcast_win32_impl (GCond * cond)
{
  guint i;
  EnterCriticalSection (&cond->lock);

  for (i = 0; i < cond->array->len; i++)
    SetEvent (g_ptr_array_index (cond->array, i));

  g_ptr_array_set_size (cond->array, 0);
  LeaveCriticalSection (&cond->lock);
}

static gboolean
g_cond_wait_internal (GCond *cond,
		      GMutex *entered_mutex,
		      gulong milliseconds)
{
  gulong retval;
  HANDLE event = TlsGetValue (g_cond_event_tls);

  if (!event)
    {
      win32_check_for_error (event = CreateEvent (0, FALSE, FALSE, NULL));
      TlsSetValue (g_cond_event_tls, event);
    }

  EnterCriticalSection (&cond->lock);

  /* The event must not be signaled. Check this */
  g_assert (WaitForSingleObject (event, 0) == WAIT_TIMEOUT);

  g_ptr_array_add (cond->array, event);
  LeaveCriticalSection (&cond->lock);

  g_mutex_unlock (entered_mutex);

  win32_check_for_error (WAIT_FAILED !=
			 (retval = WaitForSingleObject (event, milliseconds)));

  g_mutex_lock (entered_mutex);

  if (retval == WAIT_TIMEOUT)
    {
      EnterCriticalSection (&cond->lock);
      g_ptr_array_remove (cond->array, event);

      /* In the meantime we could have been signaled, so we must again
       * wait for the signal, this time with no timeout, to reset
       * it. retval is set again to honour the late arrival of the
       * signal */
      win32_check_for_error (WAIT_FAILED != 
			     (retval = WaitForSingleObject (event, 0)));

      LeaveCriticalSection (&cond->lock);
    }

#ifndef G_DISABLE_ASSERT
  EnterCriticalSection (&cond->lock);

  /* Now event must not be inside the array, check this */
  g_assert (g_ptr_array_remove (cond->array, event) == FALSE);

  LeaveCriticalSection (&cond->lock);
#endif /* !G_DISABLE_ASSERT */

  return retval != WAIT_TIMEOUT;
}

static void     
g_cond_wait_win32_impl (GCond *cond,
			GMutex *entered_mutex)
{
  g_return_if_fail (cond != NULL);
  g_return_if_fail (entered_mutex != NULL);

  g_cond_wait_internal (cond, entered_mutex, INFINITE);
}

static gboolean
g_cond_timed_wait_win32_impl (GCond *cond, 
			      GMutex *entered_mutex,
			      GTimeVal *abs_time)
{
  GTimeVal current_time;
  gulong to_wait;

  g_return_val_if_fail (cond != NULL, FALSE);
  g_return_val_if_fail (entered_mutex != NULL, FALSE);

  if (!abs_time)
    to_wait = INFINITE;
  else
    {
      g_get_current_time (&current_time);
      if (abs_time->tv_sec < current_time.tv_sec ||
	  (abs_time->tv_sec == current_time.tv_sec &&
	   abs_time->tv_usec <= current_time.tv_usec))
	to_wait = 0;
      else
	to_wait = (abs_time->tv_sec - current_time.tv_sec) * 1000 +
	  (abs_time->tv_usec - current_time.tv_usec) / 1000;      
    }
  
  return g_cond_wait_internal (cond, entered_mutex, to_wait);
}

static void
g_cond_free_win32_impl (GCond * cond)
{
  DeleteCriticalSection (&cond->lock);
  g_ptr_array_free (cond->array, TRUE);
  g_free (cond);
}

static GPrivate *
g_private_new_win32_impl (GDestroyNotify destructor)
{
  GPrivate *result;
  EnterCriticalSection (&g_thread_global_spinlock);
  if (g_private_next >= G_PRIVATE_MAX)
    {
      char buf[100];
      sprintf (buf,
	       "Too many GPrivate allocated. Their number is limited to %d.",
	       G_PRIVATE_MAX);
      MessageBox (NULL, buf, NULL, MB_ICONERROR|MB_SETFOREGROUND);
      if (IsDebuggerPresent ())
	G_BREAKPOINT ();
      abort ();
    }
  g_private_destructors[g_private_next] = destructor;
  result = GUINT_TO_POINTER (g_private_next);
  g_private_next++;
  LeaveCriticalSection (&g_thread_global_spinlock);

  return result;
}

/* NOTE: the functions g_private_get and g_private_set may not use
   functions from gmem.c and gmessages.c */

static void
g_private_set_win32_impl (GPrivate * private_key, gpointer value)
{
  gpointer* array = TlsGetValue (g_private_tls);
  guint index = GPOINTER_TO_UINT (private_key);

  if (index >= G_PRIVATE_MAX)
      return;

  if (!array)
    {
      array = (gpointer*) calloc (G_PRIVATE_MAX, sizeof (gpointer));
      TlsSetValue (g_private_tls, array);
    }

  array[index] = value;
}

static gpointer
g_private_get_win32_impl (GPrivate * private_key)
{
  gpointer* array = TlsGetValue (g_private_tls);
  guint index = GPOINTER_TO_UINT (private_key);

  if (index >= G_PRIVATE_MAX || !array)
    return NULL;

  return array[index];
}

static void
g_thread_set_priority_win32_impl (gpointer thread, GThreadPriority priority)
{
  GThreadData *target = *(GThreadData **)thread;

  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);

  win32_check_for_error (SetThreadPriority (target->thread,  
					    g_thread_priority_map [priority]));
}

static void
g_thread_self_win32_impl (gpointer thread)
{  
  GThreadData *self = TlsGetValue (g_thread_self_tls);

  if (!self)
    {
      /* This should only happen for the main thread! */
      HANDLE handle = GetCurrentThread ();
      HANDLE process = GetCurrentProcess ();
      self = g_new (GThreadData, 1);
      win32_check_for_error (DuplicateHandle (process, handle, process, 
					      &self->thread, 0, FALSE, 
					      DUPLICATE_SAME_ACCESS));
      win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
      self->func = NULL;
      self->data = NULL;      
      self->joinable = FALSE;
    }

  *(GThreadData **)thread = self;
}

static void 
g_thread_exit_win32_impl (void)
{
  GThreadData *self = TlsGetValue (g_thread_self_tls);
  guint i, private_max;
  gpointer *array = TlsGetValue (g_private_tls);
  HANDLE event = TlsGetValue (g_cond_event_tls);

  EnterCriticalSection (&g_thread_global_spinlock);
  private_max = g_private_next;
  LeaveCriticalSection (&g_thread_global_spinlock);

  if (array)
    {
      gboolean some_data_non_null;

      do {
	some_data_non_null = FALSE;
	for (i = 0; i < private_max; i++)
	  {
	    GDestroyNotify destructor = g_private_destructors[i];
	    GDestroyNotify data = array[i];
	    
	    if (data)
	      some_data_non_null = TRUE;

	    array[i] = NULL;
	    
	    if (destructor && data)
	      destructor (data);
	  }
      } while (some_data_non_null);

      free (array);

      win32_check_for_error (TlsSetValue (g_private_tls, NULL));
    }
  
  if (self)
    {
      if (!self->joinable)
	{
	  win32_check_for_error (CloseHandle (self->thread));
	  g_free (self);
	}
      win32_check_for_error (TlsSetValue (g_thread_self_tls, NULL));
    }

  if (event)
    {
      CloseHandle (event);
      win32_check_for_error (TlsSetValue (g_cond_event_tls, NULL));
    }

  _endthreadex (0);
}

static guint __stdcall
g_thread_proxy (gpointer data)
{
  GThreadData *self = (GThreadData*) data;

  win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
  
  self->func (self->data);

  g_thread_exit_win32_impl ();

  g_assert_not_reached ();

  return 0;
}

static void
g_thread_create_win32_impl (GThreadFunc func, 
			    gpointer data, 
			    gulong stack_size,
			    gboolean joinable,
			    gboolean bound,
			    GThreadPriority priority,
			    gpointer thread,
			    GError **error)
{     
  guint ignore;
  GThreadData *retval;

  g_return_if_fail (func);
  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
  
  retval = g_new(GThreadData, 1);
  retval->func = func;
  retval->data = data;
  
  retval->joinable = joinable;

  retval->thread = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_proxy, 
					    retval, 0, &ignore);

  if (retval->thread == NULL)
    {
      gchar *win_error = g_win32_error_message (GetLastError ());
      g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
                   "Error creating thread: %s", win_error);
      g_free (retval);
      g_free (win_error);
      return;
    }

  *(GThreadData **)thread = retval;

  g_thread_set_priority_win32_impl (thread, priority);
}

static void 
g_thread_yield_win32_impl (void)
{
  Sleep(0);
}

static void
g_thread_join_win32_impl (gpointer thread)
{
  GThreadData *target = *(GThreadData **)thread;

  g_return_if_fail (target->joinable);

  win32_check_for_error (WAIT_FAILED != 
			 WaitForSingleObject (target->thread, INFINITE));

  win32_check_for_error (CloseHandle (target->thread));
  g_free (target);
}

static GThreadFunctions g_thread_functions_for_glib_use_default =
{
  g_mutex_new_win32_impl,           /* mutex */
  g_mutex_lock_win32_impl,
  g_mutex_trylock_win32_impl,
  g_mutex_unlock_win32_impl,
  g_mutex_free_win32_impl,
  g_cond_new_win32_impl,            /* condition */
  g_cond_signal_win32_impl,
  g_cond_broadcast_win32_impl,
  g_cond_wait_win32_impl,
  g_cond_timed_wait_win32_impl,
  g_cond_free_win32_impl,
  g_private_new_win32_impl,         /* private thread data */
  g_private_get_win32_impl,
  g_private_set_win32_impl,
  g_thread_create_win32_impl,       /* thread */
  g_thread_yield_win32_impl,
  g_thread_join_win32_impl,
  g_thread_exit_win32_impl,
  g_thread_set_priority_win32_impl,
  g_thread_self_win32_impl,
  NULL                              /* no equal function necessary */
};

#define HAVE_G_THREAD_IMPL_INIT
static void
g_thread_impl_init ()
{
  static gboolean beenhere = FALSE;
  HMODULE kernel32;

  if (beenhere)
    return;

  beenhere = TRUE;
  
  win32_check_for_error (TLS_OUT_OF_INDEXES != 
			 (g_thread_self_tls = TlsAlloc ()));
  win32_check_for_error (TLS_OUT_OF_INDEXES != 
			 (g_private_tls = TlsAlloc ()));
  win32_check_for_error (TLS_OUT_OF_INDEXES != 
			 (g_cond_event_tls = TlsAlloc ()));
  InitializeCriticalSection (&g_thread_global_spinlock);

  /* Here we are looking for TryEnterCriticalSection in KERNEL32.DLL,
   * if it is found, we can use the faster critical sections instead
   * of mutexes. Note however that
   * http://www2.awl.com/cseng/titles/0-201-63465-1/csmutx.htm indicates,
   * that critical sections might not be ideal after all on SMP machines */
  kernel32 = GetModuleHandle ("KERNEL32.DLL");
  if (kernel32)
    {
      try_enter_critical_section = (GTryEnterCriticalSectionFunc)
	GetProcAddress(kernel32, "TryEnterCriticalSection");
      
      /* Even if TryEnterCriticalSection is found, it is not
       * necessarily working..., we have to check it */
      if (try_enter_critical_section && 
	  try_enter_critical_section (&g_thread_global_spinlock))
	{
	  LeaveCriticalSection (&g_thread_global_spinlock);

	  g_thread_functions_for_glib_use_default.mutex_new =
	    g_mutex_new_win32_cs_impl;
	  g_thread_functions_for_glib_use_default.mutex_lock =
	    g_mutex_lock_win32_cs_impl;
	  g_thread_functions_for_glib_use_default.mutex_trylock =
	    g_mutex_trylock_win32_cs_impl;
	  g_thread_functions_for_glib_use_default.mutex_unlock =
	    g_mutex_unlock_win32_cs_impl;
	  g_thread_functions_for_glib_use_default.mutex_free =
	    g_mutex_free_win32_cs_impl;
	}
    }
}
