Package: php5
Version: 5.2.0-8+etch13
Severity: normal
Tags: patch, upstream


php_curl_stream_read() in ext/curl/streams.c always calls select() after
firing up a connection.  however, when the php client is under heavy
load, the server might have already responded, and the last call to
curl_multi_perform() before entering the loop might have received all
the data and closed the connection.  at this point, curl_multi_fdset()
in the loop returns maxfs == -1, and the following select turns into a
pointless 15 sec sleep. 

I believe this problem is related to http://bugs.php.net/bug.php?id=23258

please see the attached patch.
regards
g.b.

-- System Information:
Debian Release: 4.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/dash
Kernel: Linux 2.6.18-6-686
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages php5 depends on:
ii  libapache2-mod-php5       5.2.0-8+etch13 server-side, HTML-embedded scripti
ii  php5-common               5.2.0-8+etch13 Common files for packages built fr

php5 recommends no packages.

-- no debconf information
diff -Nur php-5.1.6.old/ext/curl/streams.c php-5.1.6/ext/curl/streams.c
--- php-5.1.6.old/ext/curl/streams.c	2006-08-10 19:16:35.000000000 +0200
+++ php-5.1.6/ext/curl/streams.c	2009-02-04 17:16:39.000000000 +0100
@@ -160,7 +160,8 @@
 			tv.tv_sec = 15; /* TODO: allow this to be configured from the script */
 
 			/* wait for data */
-			switch (select(curlstream->maxfd + 1, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &tv)) {
+			switch ((curlstream->maxfd < 0) ? 1 : 
+					select(curlstream->maxfd + 1, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &tv)) {
 				case -1:
 					/* error */
 					return 0;
@@ -173,7 +174,8 @@
 						curlstream->mcode = curl_multi_perform(curlstream->multi, &curlstream->pending);
 					} while (curlstream->mcode == CURLM_CALL_MULTI_PERFORM);
 			}
-		} while (curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending > 0);
+		} while (curlstream->maxfd >= 0 &&
+				curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending > 0);
 
 	}
 

Reply via email to