/*
 * msvcrt.dll thread functions
 *
 * Copyright 2000 Jon Griffiths
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include "msvcrt.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);

/********************************************************************/

typedef struct {
  HANDLE thread;
  MSVCRT__beginthread_start_routine_t start_address;
  void *arglist;
} _beginthread_trampoline_t;

/*********************************************************************
 *		msvcrt_get_thread_data
 *
 * Return the thread local storage structure.
 */
thread_data_t *msvcrt_get_thread_data(void)
{
    thread_data_t *ptr;
    DWORD err = GetLastError();  /* need to preserve last error */

    if (!(ptr = TlsGetValue( msvcrt_tls_index )))
    {
        if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) )))
            _amsg_exit( _RT_THREAD );
        if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD );
        ptr->tid = GetCurrentThreadId();
        ptr->handle = INVALID_HANDLE_VALUE;
        ptr->random_seed = 1;
        ptr->locinfo = MSVCRT_locale->locinfo;
        ptr->mbcinfo = MSVCRT_locale->mbcinfo;
    }
    SetLastError( err );
    return ptr;
}

/*********************************************************************
 *		_endthread (MSVCRT.@)
 */
void CDECL _endthread(void)
{
  thread_data_t *tls;

  TRACE("(void)\n");

  tls = TlsGetValue(msvcrt_tls_index);
  if (tls && tls->handle != INVALID_HANDLE_VALUE)
  {
      CloseHandle(tls->handle);
      tls->handle = INVALID_HANDLE_VALUE;
  } else
      WARN("tls=%p tls->handle=%p\n", tls, tls ? tls->handle : INVALID_HANDLE_VALUE);

  /* FIXME */
  ExitThread(0);
}

/*********************************************************************
 *		_endthreadex (MSVCRT.@)
 */
void CDECL _endthreadex(
  unsigned int retval) /* [in] Thread exit code */
{
  TRACE("(%d)\n", retval);

  /* FIXME */
  ExitThread(retval);
}

/*********************************************************************
 *		_beginthread_trampoline
 */
static DWORD CALLBACK _beginthread_trampoline(LPVOID arg)
{
    _beginthread_trampoline_t local_trampoline;
    thread_data_t *data = msvcrt_get_thread_data();

    memcpy(&local_trampoline,arg,sizeof(local_trampoline));
    data->handle = local_trampoline.thread;
    MSVCRT_free(arg);

    local_trampoline.start_address(local_trampoline.arglist);
    _endthread();
    return 0;
}

/*********************************************************************
 *		_beginthread (MSVCRT.@)
 */
MSVCRT_uintptr_t CDECL _beginthread(
  MSVCRT__beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */
  unsigned int stack_size, /* [in] Stack size for new thread or 0 */
  void *arglist)           /* [in] Argument list to be passed to new thread or NULL */
{
  _beginthread_trampoline_t* trampoline;
  HANDLE thread;

  TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist);

  trampoline = MSVCRT_malloc(sizeof(*trampoline));
  if(!trampoline) {
      *MSVCRT__errno() = MSVCRT_EAGAIN;
      return -1;
  }

  thread = CreateThread(NULL, stack_size, _beginthread_trampoline,
          trampoline, CREATE_SUSPENDED, NULL);
  if(!thread) {
      MSVCRT_free(trampoline);
      *MSVCRT__errno() = MSVCRT_EAGAIN;
      return -1;
  }

  trampoline->thread = thread;
  trampoline->start_address = start_address;
  trampoline->arglist = arglist;

  if(ResumeThread(thread) == -1) {
      MSVCRT_free(trampoline);
      *MSVCRT__errno() = MSVCRT_EAGAIN;
      return -1;
  }

  return (MSVCRT_uintptr_t)thread;
}

/*********************************************************************
 *		_beginthreadex (MSVCRT.@)
 */
MSVCRT_uintptr_t CDECL _beginthreadex(
  void *security,          /* [in] Security descriptor for new thread; must be NULL for Windows 9x applications */
  unsigned int stack_size, /* [in] Stack size for new thread or 0 */
  MSVCRT__beginthreadex_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */
  void *arglist,           /* [in] Argument list to be passed to new thread or NULL */
  unsigned int initflag,   /* [in] Initial state of new thread (0 for running or CREATE_SUSPEND for suspended) */
  unsigned int *thrdaddr)  /* [out] Points to a 32-bit variable that receives the thread identifier */
{
  TRACE("(%p, %d, %p, %p, %d, %p)\n", security, stack_size, start_address, arglist, initflag, thrdaddr);

  /* FIXME */
  return (MSVCRT_uintptr_t)CreateThread(security, stack_size,
				     start_address, arglist,
				     initflag, thrdaddr);
}

/*********************************************************************
 *		_getptd (MSVCR80.@)
 */
thread_data_t* CDECL _getptd(void)
{
    FIXME("returns undocumented/not fully filled data\n");
    return msvcrt_get_thread_data();
}
