/***********************************************************
Copyright (c) 2000, BeOpen.com.
Copyright (c) 1995-2000, Corporation for National Research Initiatives.
Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
All rights reserved.

See the file "Misc/COPYRIGHT" for information on usage and
redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
******************************************************************/

/* select - Module containing unix select(2) call.
   Under Unix, the file descriptors are small integers.
   Under Win32, select only exists for sockets, and sockets may
   have any value except INVALID_SOCKET.
   Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
   >= 0.
*/

#include "Python.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif

#ifdef __sgi
/* This is missing from unistd.h */
extern void bzero(void *, int);
#endif

#ifndef DONT_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#if defined(PYOS_OS2)
#include <sys/time.h>
#include <utils.h>
#endif

#ifdef MS_WINDOWS
#include <winsock.h>
#else
#ifdef __BEOS__
#include <net/socket.h>
#define SOCKET int
#else
#define SOCKET int
#endif
#endif

static PyObject *SelectError;

/* list of Python objects and their file descriptor */
typedef struct {
	PyObject *obj;			     /* owned reference */
	SOCKET fd;
	int sentinel;			     /* -1 == sentinel */
} pylist;

static void
reap_obj(pylist fd2obj[FD_SETSIZE + 3])
{
	int i;
	for (i = 0; i < FD_SETSIZE + 3 && fd2obj[i].sentinel >= 0; i++) {
		Py_XDECREF(fd2obj[i].obj);
		fd2obj[i].obj = NULL;
	}
	fd2obj[0].sentinel = -1;
}


/* returns -1 and sets the Python exception if an error occurred, otherwise
   returns a number >= 0
*/
static int
list2set(PyObject *list, fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
{
	int i;
	int max = -1;
	int index = 0;
	int len = PyList_Size(list);
	PyObject* o = NULL;

	fd2obj[0].obj = (PyObject*)0;	     /* set list to zero size */
	FD_ZERO(set);

	for (i = 0; i < len; i++)  {
		SOCKET v;

		/* any intervening fileno() calls could decr this refcnt */
		if (!(o = PyList_GetItem(list, i)))
                    return -1;

		Py_INCREF(o);
		v = PyObject_AsFileDescriptor( o );
		if (v == -1) goto finally;

#if defined(_MSC_VER)
		max = 0;		     /* not used for Win32 */
#else  /* !_MSC_VER */
		if (v < 0 || v >= FD_SETSIZE) {
			PyErr_SetString(PyExc_ValueError,
				    "filedescriptor out of range in select()");
			goto finally;
		}
		if (v > max)
			max = v;
#endif /* _MSC_VER */
		FD_SET(v, set);

		/* add object and its file descriptor to the list */
		if (index >= FD_SETSIZE) {
			PyErr_SetString(PyExc_ValueError,
				      "too many file descriptors in select()");
			goto finally;
		}
		fd2obj[index].obj = o;
		fd2obj[index].fd = v;
		fd2obj[index].sentinel = 0;
		fd2obj[++index].sentinel = -1;
	}
	return max+1;

  finally:
	Py_XDECREF(o);
	return -1;
}

/* returns NULL and sets the Python exception if an error occurred */
static PyObject *
set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 3])
{
	int i, j, count=0;
	PyObject *list, *o;
	SOCKET fd;

	for (j = 0; fd2obj[j].sentinel >= 0; j++) {
		if (FD_ISSET(fd2obj[j].fd, set))
			count++;
	}
	list = PyList_New(count);
	if (!list)
		return NULL;

	i = 0;
	for (j = 0; fd2obj[j].sentinel >= 0; j++) {
		fd = fd2obj[j].fd;
		if (FD_ISSET(fd, set)) {
#ifndef _MSC_VER
			if (fd > FD_SETSIZE) {
				PyErr_SetString(PyExc_SystemError,
			   "filedescriptor out of range returned in select()");
				goto finally;
			}
#endif
			o = fd2obj[j].obj;
			fd2obj[j].obj = NULL;
			/* transfer ownership */
			if (PyList_SetItem(list, i, o) < 0)
				goto finally;

			i++;
		}
	}
	return list;
  finally:
	Py_DECREF(list);
	return NULL;
}

    
static PyObject *
select_select(PyObject *self, PyObject *args)
{
#ifdef MS_WINDOWS
	/* This would be an awful lot of stack space on Windows! */
	pylist *rfd2obj, *wfd2obj, *efd2obj;
#else
	pylist rfd2obj[FD_SETSIZE + 3];
	pylist wfd2obj[FD_SETSIZE + 3];
	pylist efd2obj[FD_SETSIZE + 3];
#endif
	PyObject *ifdlist, *ofdlist, *efdlist;
	PyObject *ret = NULL;
	PyObject *tout = Py_None;
	fd_set ifdset, ofdset, efdset;
	double timeout;
	struct timeval tv, *tvp;
	long seconds;
	int imax, omax, emax, max;
	int n;

	/* convert arguments */
	if (!PyArg_ParseTuple(args, "OOO|O:select",
			      &ifdlist, &ofdlist, &efdlist, &tout))
		return NULL;

	if (tout == Py_None)
		tvp = (struct timeval *)0;
	else if (!PyArg_Parse(tout, "d", &timeout)) {
		PyErr_SetString(PyExc_TypeError,
				"timeout must be a float or None");
		return NULL;
	}
	else {
		if (timeout > (double)LONG_MAX) {
			PyErr_SetString(PyExc_OverflowError, "timeout period too long");
			return NULL;
		}
		seconds = (long)timeout;
		timeout = timeout - (double)seconds;
		tv.tv_sec = seconds;
		tv.tv_usec = (long)(timeout*1000000.0);
		tvp = &tv;
	}

	/* sanity check first three arguments */
	if (!PyList_Check(ifdlist) ||
	    !PyList_Check(ofdlist) ||
	    !PyList_Check(efdlist))
	{
		PyErr_SetString(PyExc_TypeError,
				"arguments 1-3 must be lists");
		return NULL;
	}

#ifdef MS_WINDOWS
	/* Allocate memory for the lists */
	rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
	wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
	efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3);
	if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
		if (rfd2obj) PyMem_DEL(rfd2obj);
		if (wfd2obj) PyMem_DEL(wfd2obj);
		if (efd2obj) PyMem_DEL(efd2obj);
		return NULL;
	}
#endif
	/* Convert lists to fd_sets, and get maximum fd number
	 * propagates the Python exception set in list2set()
	 */
	rfd2obj[0].sentinel = -1;
	wfd2obj[0].sentinel = -1;
	efd2obj[0].sentinel = -1;
	if ((imax=list2set(ifdlist, &ifdset, rfd2obj)) < 0) 
		goto finally;
	if ((omax=list2set(ofdlist, &ofdset, wfd2obj)) < 0) 
		goto finally;
	if ((emax=list2set(efdlist, &efdset, efd2obj)) < 0) 
		goto finally;
	max = imax;
	if (omax > max) max = omax;
	if (emax > max) max = emax;

	Py_BEGIN_ALLOW_THREADS
	n = select(max, &ifdset, &ofdset, &efdset, tvp);
	Py_END_ALLOW_THREADS

	if (n < 0) {
		PyErr_SetFromErrno(SelectError);
	}
	else if (n == 0) {
                /* optimization */
		ifdlist = PyList_New(0);
		if (ifdlist) {
			ret = Py_BuildValue("OOO", ifdlist, ifdlist, ifdlist);
			Py_DECREF(ifdlist);
		}
	}
	else {
		/* any of these three calls can raise an exception.  it's more
		   convenient to test for this after all three calls... but
		   is that acceptable?
		*/
		ifdlist = set2list(&ifdset, rfd2obj);
		ofdlist = set2list(&ofdset, wfd2obj);
		efdlist = set2list(&efdset, efd2obj);
		if (PyErr_Occurred())
			ret = NULL;
		else
			ret = Py_BuildValue("OOO", ifdlist, ofdlist, efdlist);

		Py_DECREF(ifdlist);
		Py_DECREF(ofdlist);
		Py_DECREF(efdlist);
	}
	
  finally:
	reap_obj(rfd2obj);
	reap_obj(wfd2obj);
	reap_obj(efd2obj);
#ifdef MS_WINDOWS
	PyMem_DEL(rfd2obj);
	PyMem_DEL(wfd2obj);
	PyMem_DEL(efd2obj);
#endif
	return ret;
}

#ifdef HAVE_POLL
/* 
 * poll() support
 */

typedef struct {
	PyObject_HEAD
	PyObject *dict;
	int ufd_uptodate; 
	int ufd_len;
        struct pollfd *ufds;
} pollObject;

staticforward PyTypeObject poll_Type;

/* Update the malloc'ed array of pollfds to match the dictionary 
   contained within a pollObject.  Return 1 on success, 0 on an error.
*/

static int
update_ufd_array(pollObject *self)
{
	int i, j, pos;
	PyObject *key, *value;

	self->ufd_len = PyDict_Size(self->dict);
	PyMem_Resize(self->ufds, struct pollfd, self->ufd_len);
	if (self->ufds == NULL) {
		PyErr_NoMemory();
		return 0;
	}

	i = pos = 0;
	while ((j = PyDict_Next(self->dict, &pos, &key, &value))) {
		self->ufds[i].fd = PyInt_AsLong(key);
		self->ufds[i].events = PyInt_AsLong(value);
		i++;
	}
	self->ufd_uptodate = 1;
	return 1;
}

static char poll_register_doc[] =
"register(fd [, eventmask] ) -> None\n\n\
Register a file descriptor with the polling object.\n\
fd -- either an integer, or an object with a fileno() method returning an int.\n\
events -- an optional bitmask describing the type of events to check for";

static PyObject *
poll_register(pollObject *self, PyObject *args) 
{
	PyObject *o, *key, *value;
	int fd, events = POLLIN | POLLPRI | POLLOUT;

	if (!PyArg_ParseTuple(args, "O|i", &o, &events)) {
		return NULL;
	}
  
	fd = PyObject_AsFileDescriptor(o);
	if (fd == -1) return NULL;

	/* Add entry to the internal dictionary: the key is the 
	   file descriptor, and the value is the event mask. */
	if ( (NULL == (key = PyInt_FromLong(fd))) ||
	     (NULL == (value = PyInt_FromLong(events))) ||
	     (PyDict_SetItem(self->dict, key, value)) == -1) {
		return NULL;
	}
	self->ufd_uptodate = 0;
		       
	Py_INCREF(Py_None);
	return Py_None;
}

static char poll_unregister_doc[] =
"unregister(fd) -> None\n\n\
Remove a file descriptor being tracked by the polling object.";

static PyObject *
poll_unregister(pollObject *self, PyObject *args) 
{
	PyObject *o, *key;
	int fd;

	if (!PyArg_ParseTuple(args, "O", &o)) {
		return NULL;
	}
  
	fd = PyObject_AsFileDescriptor( o );
	if (fd == -1) 
		return NULL;

	/* Check whether the fd is already in the array */
	key = PyInt_FromLong(fd);
	if (key == NULL) 
		return NULL;

	if (PyDict_DelItem(self->dict, key) == -1) {
		Py_DECREF(key);
		/* This will simply raise the KeyError set by PyDict_DelItem
		   if the file descriptor isn't registered. */
		return NULL;
	}

	Py_DECREF(key);
	self->ufd_uptodate = 0;

	Py_INCREF(Py_None);
	return Py_None;
}

static char poll_poll_doc[] =
"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
Polls the set of registered file descriptors, returning a list containing \n\
any descriptors that have events or errors to report.";

static PyObject *
poll_poll(pollObject *self, PyObject *args) 
{
	PyObject *result_list = NULL, *tout = NULL;
	int timeout = 0, poll_result, i, j;
	PyObject *value = NULL, *num = NULL;

	if (!PyArg_ParseTuple(args, "|O", &tout)) {
		return NULL;
	}

	/* Check values for timeout */
	if (tout == NULL || tout == Py_None)
		timeout = -1;
	else if (!PyArg_Parse(tout, "i", &timeout)) {
		PyErr_SetString(PyExc_TypeError,
				"timeout must be an integer or None");
		return NULL;
	}

	/* Ensure the ufd array is up to date */
	if (!self->ufd_uptodate) 
		if (update_ufd_array(self) == 0)
			return NULL;

	/* call poll() */
	Py_BEGIN_ALLOW_THREADS;
	poll_result = poll(self->ufds, self->ufd_len, timeout);
	Py_END_ALLOW_THREADS;
 
	if (poll_result < 0) {
		PyErr_SetFromErrno(SelectError);
		return NULL;
	} 
       
	/* build the result list */
  
	result_list = PyList_New(poll_result);
	if (!result_list) 
		return NULL;
	else {
		for (i = 0, j = 0; j < poll_result; j++) {
 			/* skip to the next fired descriptor */
 			while (!self->ufds[i].revents) {
 				i++;
 			}
			/* if we hit a NULL return, set value to NULL
			   and break out of loop; code at end will
			   clean up result_list */
			value = PyTuple_New(2);
			if (value == NULL)
				goto error;
			num = PyInt_FromLong(self->ufds[i].fd);
			if (num == NULL) {
				Py_DECREF(value);
				goto error;
			}
			PyTuple_SET_ITEM(value, 0, num);

			num = PyInt_FromLong(self->ufds[i].revents);
			if (num == NULL) {
				Py_DECREF(value);
				goto error;
			}
			PyTuple_SET_ITEM(value, 1, num);
 			if ((PyList_SetItem(result_list, j, value)) == -1) {
				Py_DECREF(value);
				goto error;
 			}
 			i++;
 		}
 	}
 	return result_list;

  error:
	Py_DECREF(result_list);
	return NULL;
}

static PyMethodDef poll_methods[] = {
	{"register",	(PyCFunction)poll_register,	
	 METH_VARARGS,  poll_register_doc},
	{"unregister",	(PyCFunction)poll_unregister,	
	 METH_VARARGS,  poll_unregister_doc},
	{"poll",	(PyCFunction)poll_poll,	
	 METH_VARARGS,  poll_poll_doc},
	{NULL,		NULL}		/* sentinel */
};

static pollObject *
newPollObject()
{
        pollObject *self;
	self = PyObject_New(pollObject, &poll_Type);
	if (self == NULL)
		return NULL;
	/* ufd_uptodate is a Boolean, denoting whether the 
	   array pointed to by ufds matches the contents of the dictionary. */
	self->ufd_uptodate = 0;
	self->ufds = NULL;
	self->dict = PyDict_New();
	if (self->dict == NULL) {
		Py_DECREF(self);
		return NULL;
	}
	return self;
}

static void
poll_dealloc(pollObject *self)
{
	if (self->ufds != NULL)
		PyMem_DEL(self->ufds);
	Py_XDECREF(self->dict);
  	PyObject_Del(self);
}

static PyObject *
poll_getattr(pollObject *self, char *name)
{
	return Py_FindMethod(poll_methods, (PyObject *)self, name);
}

statichere PyTypeObject poll_Type = {
	/* The ob_type field must be initialized in the module init function
	 * to be portable to Windows without using C++. */
	PyObject_HEAD_INIT(NULL)
	0,			/*ob_size*/
	"poll",			/*tp_name*/
	sizeof(pollObject),	/*tp_basicsize*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)poll_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)poll_getattr, /*tp_getattr*/
	0,                      /*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
	0,			/*tp_hash*/
};

static char poll_doc[] = 
"Returns a polling object, which supports registering and\n\
unregistering file descriptors, and then polling them for I/O events.";

static PyObject *
select_poll(PyObject *self, PyObject *args)
{
	pollObject *rv;
	
	if (!PyArg_ParseTuple(args, ":poll"))
		return NULL;
	rv = newPollObject();
	if ( rv == NULL )
		return NULL;
	return (PyObject *)rv;
}
#endif /* HAVE_POLL */

static char select_doc[] =
"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
\n\
Wait until one or more file descriptors are ready for some kind of I/O.\n\
The first three arguments are lists of file descriptors to be waited for:\n\
rlist -- wait until ready for reading\n\
wlist -- wait until ready for writing\n\
xlist -- wait for an ``exceptional condition''\n\
If only one kind of condition is required, pass [] for the other lists.\n\
A file descriptor is either a socket or file object, or a small integer\n\
gotten from a fileno() method call on one of those.\n\
\n\
The optional 4th argument specifies a timeout in seconds; it may be\n\
a floating point number to specify fractions of seconds.  If it is absent\n\
or None, the call will never time out.\n\
\n\
The return value is a tuple of three lists corresponding to the first three\n\
arguments; each contains the subset of the corresponding file descriptors\n\
that are ready.\n\
\n\
*** IMPORTANT NOTICE ***\n\
On Windows, only sockets are supported; on Unix, all file descriptors.";

static PyMethodDef select_methods[] = {
    {"select",	select_select, METH_VARARGS, select_doc},
#ifdef HAVE_POLL
    {"poll",    select_poll,   METH_VARARGS, poll_doc},
#endif /* HAVE_POLL */
    {0,  	0},			     /* sentinel */
};

static char module_doc[] =
"This module supports asynchronous I/O on multiple file descriptors.\n\
\n\
*** IMPORTANT NOTICE ***\n\
On Windows, only sockets are supported; on Unix, all file descriptors.";

/*
 * Convenience routine to export an integer value.
 * For simplicity, errors (which are unlikely anyway) are ignored.
 */

static void
insint(PyObject *d, char *name, int value)
{
	PyObject *v = PyInt_FromLong((long) value);
	if (v == NULL) {
		/* Don't bother reporting this error */
		PyErr_Clear();
	}
	else {
		PyDict_SetItemString(d, name, v);
		Py_DECREF(v);
	}
}

DL_EXPORT(void)
initselect(void)
{
	PyObject *m, *d;
	m = Py_InitModule3("select", select_methods, module_doc);
	d = PyModule_GetDict(m);
	SelectError = PyErr_NewException("select.error", NULL, NULL);
	PyDict_SetItemString(d, "error", SelectError);
#ifdef HAVE_POLL
	poll_Type.ob_type = &PyType_Type;
	insint(d, "POLLIN", POLLIN);
	insint(d, "POLLPRI", POLLPRI);
	insint(d, "POLLOUT", POLLOUT);
	insint(d, "POLLERR", POLLERR);
	insint(d, "POLLHUP", POLLHUP);
	insint(d, "POLLNVAL", POLLNVAL);

	insint(d, "POLLRDNORM", POLLRDNORM);
	insint(d, "POLLRDBAND", POLLRDBAND);
	insint(d, "POLLWRNORM", POLLWRNORM);
	insint(d, "POLLWRBAND", POLLWRBAND);
#ifdef POLLMSG
	insint(d, "POLLMSG", POLLMSG);
#endif
#endif /* HAVE_POLL */
}
