Commit 32fd16ec authored by Ronald Oussoren's avatar Ronald Oussoren

Patch 1471761 - test for broken poll at runtime

This patch checks if poll is broken when the select module is loaded instead
of doing so at configure-time. This functionality is only active on Mac OS X.
parent d06b6f28
...@@ -8,6 +8,13 @@ ...@@ -8,6 +8,13 @@
#include "Python.h" #include "Python.h"
#ifdef __APPLE__
/* Perform runtime testing for a broken poll on OSX to make it easier
* to use the same binary on multiple releases of the OS.
*/
#undef HAVE_BROKEN_POLL
#endif
/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined. /* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
64 is too small (too many people have bumped into that limit). 64 is too small (too many people have bumped into that limit).
Here we boost it. Here we boost it.
...@@ -618,7 +625,38 @@ select_poll(PyObject *self, PyObject *args) ...@@ -618,7 +625,38 @@ select_poll(PyObject *self, PyObject *args)
return NULL; return NULL;
return (PyObject *)rv; return (PyObject *)rv;
} }
#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
#ifdef __APPLE__
/*
* On some systems poll() sets errno on invalid file descriptors. We test
* for this at runtime because this bug may be fixed or introduced between
* OS releases.
*/
static int select_have_broken_poll(void)
{
int poll_test;
int filedes[2];
struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
/* Create a file descriptor to make invalid */
if (pipe(filedes) < 0) {
return 1;
}
poll_struct.fd = filedes[0];
close(filedes[0]);
close(filedes[1]);
poll_test = poll(&poll_struct, 1, 0);
if (poll_test < 0) {
return 1;
} else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
return 1;
}
return 0;
}
#endif /* __APPLE__ */
#endif /* HAVE_POLL */
PyDoc_STRVAR(select_doc, PyDoc_STRVAR(select_doc,
"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\ "select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
...@@ -645,9 +683,9 @@ On Windows, only sockets are supported; on Unix, all file descriptors."); ...@@ -645,9 +683,9 @@ On Windows, only sockets are supported; on Unix, all file descriptors.");
static PyMethodDef select_methods[] = { static PyMethodDef select_methods[] = {
{"select", select_select, METH_VARARGS, select_doc}, {"select", select_select, METH_VARARGS, select_doc},
#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) #if defined(HAVE_POLL)
{"poll", select_poll, METH_VARARGS, poll_doc}, {"poll", select_poll, METH_VARARGS, poll_doc},
#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */ #endif /* HAVE_POLL */
{0, 0}, /* sentinel */ {0, 0}, /* sentinel */
}; };
...@@ -668,29 +706,40 @@ initselect(void) ...@@ -668,29 +706,40 @@ initselect(void)
SelectError = PyErr_NewException("select.error", NULL, NULL); SelectError = PyErr_NewException("select.error", NULL, NULL);
Py_INCREF(SelectError); Py_INCREF(SelectError);
PyModule_AddObject(m, "error", SelectError); PyModule_AddObject(m, "error", SelectError);
#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL) #if defined(HAVE_POLL)
poll_Type.ob_type = &PyType_Type;
PyModule_AddIntConstant(m, "POLLIN", POLLIN); #ifdef __APPLE__
PyModule_AddIntConstant(m, "POLLPRI", POLLPRI); if (select_have_broken_poll()) {
PyModule_AddIntConstant(m, "POLLOUT", POLLOUT); if (PyObject_DelAttrString(m, "poll") == -1) {
PyModule_AddIntConstant(m, "POLLERR", POLLERR); PyErr_Clear();
PyModule_AddIntConstant(m, "POLLHUP", POLLHUP); }
PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL); } else {
#else
{
#endif
poll_Type.ob_type = &PyType_Type;
PyModule_AddIntConstant(m, "POLLIN", POLLIN);
PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
PyModule_AddIntConstant(m, "POLLERR", POLLERR);
PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
#ifdef POLLRDNORM #ifdef POLLRDNORM
PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM); PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
#endif #endif
#ifdef POLLRDBAND #ifdef POLLRDBAND
PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND); PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
#endif #endif
#ifdef POLLWRNORM #ifdef POLLWRNORM
PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM); PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
#endif #endif
#ifdef POLLWRBAND #ifdef POLLWRBAND
PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND); PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
#endif #endif
#ifdef POLLMSG #ifdef POLLMSG
PyModule_AddIntConstant(m, "POLLMSG", POLLMSG); PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
#endif #endif
#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */ }
#endif /* HAVE_POLL */
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment