--- Python-2.4.3/Modules/socketmodule.c 2006-02-20 10:42:37.000000000 +0100 +++ Python-2.4.3-work/Modules/socketmodule.c 2006-06-09 12:11:08.000000000 +0200 @@ -390,14 +390,22 @@ there has to be a circular reference. */ static PyTypeObject sock_type; +#ifdef HAVE_POLL +/* We prefer to use poll() if available, which can poll any fd */ +#ifdef HAVE_POLL_H +#include +#else +#include +#endif +#define IS_SELECTABLE(s) 1 /* Can we call select() with this socket without a buffer overrun? */ -#ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE +#elif Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE /* Platform can select file descriptors beyond FD_SETSIZE */ #define IS_SELECTABLE(s) 1 #else /* POSIX says selecting file descriptors beyond FD_SETSIZE has undefined behaviour. */ -#define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE) +#define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE || s->sock_timeout <= 0.0) #endif static PyObject* @@ -640,11 +648,44 @@ return 1; } -/* Do a select() on the socket, if necessary (sock_timeout > 0). +/* Do a select(), or poll() on the socket, if necessary (sock_timeout > 0). The argument writing indicates the direction. This does not raise an exception; we'll let our caller do that after they've reacquired the interpreter lock. Returns 1 on timeout, 0 otherwise. */ +#ifdef HAVE_POLL +/* Prefer poll when available: on all platforms, you can poll() any FD. + * On many (i.e. unix), you can't do this with select(). We call this + * internal_select() anyway, and retain the same semantics as for the select() + * version + */ +static int +internal_select(PySocketSockObject *s, int writing) +{ + struct pollfd pollfd; + int n, timeout; + + /* Nothing to do unless we're in timeout mode (not non-blocking) */ + if (s->sock_timeout <= 0.0) + return 0; + + /* Guard against closed socket */ + if (s->sock_fd < 0) + return 0; + + pollfd.fd = s->sock_fd; + pollfd.events = writing ? POLLOUT : POLLIN; + + /* s->sock_timeout is in seconds, timeout in ms */ + timeout = (int)(s->sock_timeout * 1000); + + n = poll(&pollfd, 1, timeout); + + if(n == 0) + return 1; + return 0; +} +#else static int internal_select(PySocketSockObject *s, int writing) { @@ -675,6 +716,7 @@ return 1; return 0; } +#endif /* Initialize a new socket object. */