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

      g_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;
	}
    }
}
