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

#if !defined(THREAD_STACK_SIZE)
#define	THREAD_STACK_SIZE	0x10000
#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, THREAD_STACK_SIZE, 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
}
