/***********************************************************
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.

STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

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

/* Thread module */
/* Interface to Sjoerd's portable C thread library */

#include "allobjects.h"
#include "modsupport.h"
#include "ceval.h"

#ifndef WITH_THREAD
Error!  The rest of Python is not compiled with thread support.
Rerun configure, adding a --with-thread option.
#endif

#include "thread.h"

extern int threads_started;

static object *ThreadError;


/* Lock objects */

typedef struct {
	OB_HEAD
	type_lock lock_lock;
} lockobject;

staticforward typeobject Locktype;

#define is_lockobject(v)		((v)->ob_type == &Locktype)

type_lock
getlocklock(lock)
	object *lock;
{
	if (lock == NULL || !is_lockobject(lock))
		return NULL;
	else
		return ((lockobject *) lock)->lock_lock;
}

static lockobject *
newlockobject()
{
	lockobject *self;
	self = NEWOBJ(lockobject, &Locktype);
	if (self == NULL)
		return NULL;
	self->lock_lock = allocate_lock();
	if (self->lock_lock == NULL) {
		DEL(self);
		self = NULL;
		err_setstr(ThreadError, "can't allocate lock");
	}
	return self;
}

static void
lock_dealloc(self)
	lockobject *self;
{
	/* Unlock the lock so it's safe to free it */
	acquire_lock(self->lock_lock, 0);
	release_lock(self->lock_lock);
	
	free_lock(self->lock_lock);
	DEL(self);
}

static object *
lock_acquire_lock(self, args)
	lockobject *self;
	object *args;
{
	int i;

	if (args != NULL) {
		if (!getargs(args, "i", &i))
			return NULL;
	}
	else
		i = 1;

	BGN_SAVE
	i = acquire_lock(self->lock_lock, i);
	END_SAVE

	if (args == NULL) {
		INCREF(None);
		return None;
	}
	else
		return newintobject((long)i);
}

static object *
lock_release_lock(self, args)
	lockobject *self;
	object *args;
{
	if (!getnoarg(args))
		return NULL;

	/* Sanity check: the lock must be locked */
	if (acquire_lock(self->lock_lock, 0)) {
		release_lock(self->lock_lock);
		err_setstr(ThreadError, "release unlocked lock");
		return NULL;
	}

	release_lock(self->lock_lock);
	INCREF(None);
	return None;
}

static object *
lock_locked_lock(self, args)
	lockobject *self;
	object *args;
{
	if (!getnoarg(args))
		return NULL;

	if (acquire_lock(self->lock_lock, 0)) {
		release_lock(self->lock_lock);
		return newintobject(0L);
	}
	return newintobject(1L);
}

static struct methodlist lock_methods[] = {
	{"acquire_lock",	(method)lock_acquire_lock},
	{"acquire",		(method)lock_acquire_lock},
	{"release_lock",	(method)lock_release_lock},
	{"release",		(method)lock_release_lock},
	{"locked_lock",		(method)lock_locked_lock},
	{"locked",		(method)lock_locked_lock},
	{NULL,			NULL}		/* sentinel */
};

static object *
lock_getattr(self, name)
	lockobject *self;
	char *name;
{
	return findmethod(lock_methods, (object *)self, name);
}

static typeobject Locktype = {
	OB_HEAD_INIT(&Typetype)
	0,				/*ob_size*/
	"lock",				/*tp_name*/
	sizeof(lockobject),		/*tp_size*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)lock_dealloc,	/*tp_dealloc*/
	0,				/*tp_print*/
	(getattrfunc)lock_getattr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
};


/* Module functions */

static void
t_bootstrap(args_raw)
	void *args_raw;
{
	object *args = (object *) args_raw;
	object *func, *arg, *res;

	threads_started++;

	restore_thread((void *)NULL);
	func = gettupleitem(args, 0);
	arg = gettupleitem(args, 1);
	res = call_object(func, arg);
	DECREF(args); /* Matches the INCREF(args) in thread_start_new_thread */
	if (res == NULL) {
		fprintf(stderr, "Unhandled exception in thread:\n");
		print_error(); /* From pythonmain.c */
	}
	(void) save_thread();
	exit_thread();
}

static object *
thread_start_new_thread(self, args)
	object *self; /* Not used */
	object *args;
{
	object *func, *arg;

	if (!getargs(args, "(OO)", &func, &arg))
		return NULL;
	INCREF(args);
	/* Initialize the interpreter's stack save/restore mechanism */
	init_save_thread();
	if (!start_new_thread(t_bootstrap, (void*) args)) {
		DECREF(args);
		err_setstr(ThreadError, "can't start new thread\n");
		return NULL;
	}
	/* Otherwise the DECREF(args) is done by t_bootstrap */
	INCREF(None);
	return None;
}

static object *
thread_exit_thread(self, args)
	object *self; /* Not used */
	object *args;
{
	if (!getnoarg(args))
		return NULL;
	(void) save_thread();
	exit_thread();
	for (;;) { } /* Should not be reached */
}

#ifndef NO_EXIT_PROG
static object *
thread_exit_prog(self, args)
	object *self; /* Not used */
	object *args;
{
	int sts;
	if (!getargs(args, "i", &sts))
		return NULL;
	goaway(sts); /* Calls exit_prog(sts) or _exit_prog(sts) */
	for (;;) { } /* Should not be reached */
}
#endif

static object *
thread_allocate_lock(self, args)
	object *self; /* Not used */
	object *args;
{
	if (!getnoarg(args))
		return NULL;
	return (object *) newlockobject();
}

static object *
thread_get_ident(self, args)
	object *self; /* Not used */
	object *args;
{
	long ident;
	if (!getnoarg(args))
		return NULL;
	ident = get_thread_ident();
	if (ident == -1) {
		err_setstr(ThreadError, "no current thread ident");
		return NULL;
	}
	return newintobject(ident);
}

static struct methodlist thread_methods[] = {
	{"start_new_thread",	(method)thread_start_new_thread},
	{"start_new",		(method)thread_start_new_thread},
	{"allocate_lock",	(method)thread_allocate_lock},
	{"allocate",		(method)thread_allocate_lock},
	{"exit_thread",		(method)thread_exit_thread},
	{"exit",		(method)thread_exit_thread},
	{"get_ident",		(method)thread_get_ident},
#ifndef NO_EXIT_PROG
	{"exit_prog",		(method)thread_exit_prog},
#endif
	{NULL,			NULL}		/* sentinel */
};


/* Initialization function */

void
initthread()
{
	object *m, *d, *x;

	/* Create the module and add the functions */
	m = initmodule("thread", thread_methods);

	/* Add a symbolic constant */
	d = getmoduledict(m);
	ThreadError = newstringobject("thread.error");
	INCREF(ThreadError);
	dictinsert(d, "error", ThreadError);

	/* Check for errors */
	if (err_occurred())
		fatal("can't initialize module thread");

	/* Initialize the C thread library */
	init_thread();
}
