/* This code implemented by cvale@netcom.com */

#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#include "os2.h"
#include "limits.h"

#include "process.h"

#if defined(PYCC_GCC)
#include <sys/builtin.h>
#include <sys/fmutex.h>
#else
long PyThread_get_thread_ident(void);
#endif

/*
 * Initialization of the C package, should not be needed.
 */
static void
PyThread__init_thread(void)
{
}

/*
 * Thread support.
 */
long
PyThread_start_new_thread(void (*func)(void *), void *arg)
{
  int aThread;
  int success = 0;

  aThread = _beginthread(func,NULL,65536,arg);

  if( aThread == -1 ) {
    success = -1;
    fprintf(stderr,"aThread failed == %d",aThread);
    dprintf(("_beginthread failed. return %ld\n", errno));
  }

  return success;
}

long
PyThread_get_thread_ident(void)
{
#if !defined(PYCC_GCC)
  PPIB pib;
  PTIB tib;
#endif

  if (!initialized)
    PyThread_init_thread();
        
#if defined(PYCC_GCC)
  return _gettid();
#else
  DosGetInfoBlocks(&tib,&pib);
  return tib->tib_ptib2->tib2_ultid;
#endif
}

static void
do_PyThread_exit_thread(int no_cleanup)
{
  dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
  if (!initialized)
    if (no_cleanup)
      _exit(0);
    else
      exit(0);
  _endthread();
}

void 
PyThread_exit_thread(void)
{
  do_PyThread_exit_thread(0);
}

void 
PyThread__exit_thread(void)
{
  do_PyThread_exit_thread(1);
}

#ifndef NO_EXIT_PROG
static void 
do_PyThread_exit_prog(int status, int no_cleanup)
{
  dprintf(("PyThread_exit_prog(%d) called\n", status));
  if (!initialized)
    if (no_cleanup)
      _exit(status);
    else
      exit(status);
}

void 
PyThread_exit_prog(int status)
{
  do_PyThread_exit_prog(status, 0);
}

void 
PyThread__exit_prog(int status)
{
  do_PyThread_exit_prog(status, 1);
}
#endif /* NO_EXIT_PROG */

/*
 * Lock support.  This is implemented with an event semaphore and critical
 * sections to make it behave more like a posix mutex than its OS/2 
 * counterparts.
 */

typedef struct os2_lock_t {
  int is_set;
  HEV changed;
} *type_os2_lock;

PyThread_type_lock 
PyThread_allocate_lock(void)
{
#if defined(PYCC_GCC)
  _fmutex *sem = malloc(sizeof(_fmutex));
  if (!initialized)
    PyThread_init_thread();
  dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
    PyThread_get_thread_ident(),
    (long)sem));
  if (_fmutex_create(sem, 0)) {
    free(sem);
    sem = NULL;
  }
  return (PyThread_type_lock) sem;
#else
  APIRET rc;
  type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));

  dprintf(("PyThread_allocate_lock called\n"));
  if (!initialized)
    PyThread_init_thread();

  lock->is_set = 0;

  DosCreateEventSem(NULL, &lock->changed, 0, 0);

  dprintf(("%ld: PyThread_allocate_lock() -> %p\n", 
           PyThread_get_thread_ident(), 
           lock->changed));

  return (PyThread_type_lock) lock;
#endif
}

void 
PyThread_free_lock(PyThread_type_lock aLock)
{
#if !defined(PYCC_GCC)
  type_os2_lock lock = (type_os2_lock)aLock;
#endif

  dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));

#if defined(PYCC_GCC)
  if (aLock) {
    _fmutex_close((_fmutex *)aLock);
    free((_fmutex *)aLock);
  }
#else
  DosCloseEventSem(lock->changed);
  free(aLock);
#endif
}

/*
 * Return 1 on success if the lock was acquired
 *
 * and 0 if the lock was not acquired.
 */
int 
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
{
#if !defined(PYCC_GCC)
  int   done = 0;
  ULONG count;
  PID   pid = 0;
  TID   tid = 0;
  type_os2_lock lock = (type_os2_lock)aLock;
#endif

  dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),
           aLock, waitflag));

#if defined(PYCC_GCC)
  /* always successful if the lock doesn't exist */
  if (aLock && _fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
      return 0;
#else
  while (!done) {
    /* if the lock is currently set, we have to wait for the state to change */
    if (lock->is_set) {
      if (!waitflag)
        return 0;
      DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
    }
    
    /* 
     * enter a critical section and try to get the semaphore.  If
     * it is still locked, we will try again.
     */
    if (DosEnterCritSec())
      return 0;

    if (!lock->is_set) {
      lock->is_set = 1;
      DosResetEventSem(lock->changed, &count);
      done = 1;
    }

    DosExitCritSec();
  }
#endif

  return 1;
}

void PyThread_release_lock(PyThread_type_lock aLock)
{
#if defined(PYCC_GCC)
  type_os2_lock lock = (type_os2_lock)aLock;
#endif

  dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));

#if defined(PYCC_GCC)
  if (aLock)
    _fmutex_release((_fmutex *)aLock);
#else
  if (!lock->is_set) {
    dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
             PyThread_get_thread_ident(), aLock, GetLastError()));
    return;
  }


  if (DosEnterCritSec()) {
    dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
             PyThread_get_thread_ident(), aLock, GetLastError()));
    return;
  }
  
  lock->is_set = 0;
  DosPostEventSem(lock->changed);
  
  DosExitCritSec();
#endif
}
