SOURCES: python-poll-instead-of-select-fix.patch (NEW) - Fix for r...

matkor matkor at pld-linux.org
Fri Oct 6 01:53:35 CEST 2006


Author: matkor                       Date: Thu Oct  5 23:53:35 2006 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- Fix for recv/send freeze when more 1k sockets are used
  https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1494314&group_id=5470

---- Files affected:
SOURCES:
   python-poll-instead-of-select-fix.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/python-poll-instead-of-select-fix.patch
diff -u /dev/null SOURCES/python-poll-instead-of-select-fix.patch:1.1
--- /dev/null	Fri Oct  6 01:53:35 2006
+++ SOURCES/python-poll-instead-of-select-fix.patch	Fri Oct  6 01:53:30 2006
@@ -0,0 +1,156 @@
+--- Python-2.4.3/Modules/_ssl.c.orig	2006-10-06 00:47:51.000000000 +0200
++++ Python-2.4.3/Modules/_ssl.c	2006-10-06 00:48:31.000000000 +0200
+@@ -26,6 +26,12 @@
+ /* Include symbols from _socket module */
+ #include "socketmodule.h"
+ 
++#if defined(HAVE_POLL_H) 
++#include <poll.h>
++#elif defined(HAVE_SYS_POLL_H)
++#include <sys/poll.h>
++#endif
++
+ /* Include OpenSSL header files */
+ #include "openssl/rsa.h"
+ #include "openssl/crypto.h"
+@@ -354,7 +360,7 @@
+ 	PyObject_Del(self);
+ }
+ 
+-/* If the socket has a timeout, do a select() on the socket.
++/* If the socket has a timeout, do a select()/poll() on the socket.
+    The argument writing indicates the direction.
+    Returns one of the possibilities in the timeout_state enum (above).
+  */
+@@ -376,6 +382,26 @@
+ 	if (s->sock_fd < 0)
+ 		return SOCKET_HAS_BEEN_CLOSED;
+ 
++	/* Prefer poll, if available, since you can poll() any fd
++	 * which can't be done with select(). */
++#ifdef HAVE_POLL
++	{
++		struct pollfd pollfd;
++		int timeout;
++
++		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 + 0.5);
++		Py_BEGIN_ALLOW_THREADS
++		rc = poll(&pollfd, 1, timeout);
++		Py_END_ALLOW_THREADS
++
++		goto normal_return;
++	}
++#endif
++
+ 	/* Guard against socket too large for select*/
+ #ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+ 	if (s->sock_fd >= FD_SETSIZE)
+@@ -396,6 +422,7 @@
+ 		rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
+ 	Py_END_ALLOW_THREADS
+ 
++normal_return:
+ 	/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
+ 	   (when we are able to write or when there's something to read) */
+ 	return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK;
+--- Python-2.4.3/Modules/socketmodule.c.orig	2006-02-20 10:42:37.000000000 +0100
++++ Python-2.4.3/Modules/socketmodule.c	2006-10-06 00:48:31.000000000 +0200
+@@ -390,14 +390,24 @@
+    there has to be a circular reference. */
+ static PyTypeObject sock_type;
+ 
+-/* Can we call select() with this socket without a buffer overrun? */
++#if defined(HAVE_POLL_H)
++#include <poll.h>
++#elif defined(HAVE_SYS_POLL_H)
++#include <sys/poll.h>
++#endif
++
+ #ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+ /* Platform can select file descriptors beyond FD_SETSIZE */
+ #define IS_SELECTABLE(s) 1
++#elif defined(HAVE_POLL)
++/* Instead of select(), we'll use poll() since poll() works on any fd. */
++#define IS_SELECTABLE(s) 1
++/* Can we call select() with this socket without a buffer overrun? */
+ #else
+ /* POSIX says selecting file descriptors beyond FD_SETSIZE
+-   has undefined behaviour. */
+-#define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE)
++   has undefined behaviour.  If there's no timeout left, we don't have to
++   call select, so it's a safe, little white lie. */
++#define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE || s->sock_timeout <= 0.0)
+ #endif
+ 
+ static PyObject*
+@@ -640,7 +650,7 @@
+ 	return 1;
+ }
+ 
+-/* Do a select() on the socket, if necessary (sock_timeout > 0).
++/* Do a select()/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.
+@@ -648,8 +658,6 @@
+ static int
+ internal_select(PySocketSockObject *s, int writing)
+ {
+-	fd_set fds;
+-	struct timeval tv;
+ 	int n;
+ 
+ 	/* Nothing to do unless we're in timeout mode (not non-blocking) */
+@@ -660,17 +668,37 @@
+ 	if (s->sock_fd < 0)
+ 		return 0;
+ 
+-	/* Construct the arguments to select */
+-	tv.tv_sec = (int)s->sock_timeout;
+-	tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
+-	FD_ZERO(&fds);
+-	FD_SET(s->sock_fd, &fds);
+-
+-	/* See if the socket is ready */
+-	if (writing)
+-		n = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
+-	else
+-		n = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
++	/* Prefer poll, if available, since you can poll() any fd
++	 * which can't be done with select(). */
++#ifdef HAVE_POLL
++	{
++		struct pollfd pollfd;
++		int timeout;
++
++		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 + 0.5); 
++		n = poll(&pollfd, 1, timeout);
++	}
++#else
++	{
++		/* Construct the arguments to select */
++		fd_set fds;
++		struct timeval tv;
++		tv.tv_sec = (int)s->sock_timeout;
++		tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
++		FD_ZERO(&fds);
++		FD_SET(s->sock_fd, &fds);
++
++		/* See if the socket is ready */
++		if (writing)
++			n = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
++		else
++			n = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
++	}
++#endif
+ 	if (n == 0)
+ 		return 1;
+ 	return 0;
================================================================


More information about the pld-cvs-commit mailing list