dmitry                                   Mon, 06 Sep 2010 11:11:40 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=303072

Log:
Fixed bug #46723 (FastCGI persistent connection is incredibly slow due to TCP 
ack delay).

Bug: http://bugs.php.net/46723 (Assigned) FastCGI is incredibly slow due to TCP 
ack delay
      
Changed paths:
    U   php/php-src/trunk/sapi/cgi/fastcgi.c

Modified: php/php-src/trunk/sapi/cgi/fastcgi.c
===================================================================
--- php/php-src/trunk/sapi/cgi/fastcgi.c        2010-09-06 11:08:43 UTC (rev 
303071)
+++ php/php-src/trunk/sapi/cgi/fastcgi.c        2010-09-06 11:11:40 UTC (rev 
303072)
@@ -67,6 +67,7 @@
 # include <sys/socket.h>
 # include <sys/un.h>
 # include <netinet/in.h>
+# include <netinet/tcp.h>
 # include <arpa/inet.h>
 # include <netdb.h>
 # include <signal.h>
@@ -337,12 +338,13 @@

 struct _fcgi_request {
        int            listen_socket;
-#ifdef _WIN32
        int            tcp;
-#endif
        int            fd;
        int            id;
        int            keep;
+#ifdef TCP_NODELAY
+       int            nodelay;
+#endif
        int            closed;

        int            in_len;
@@ -746,6 +748,10 @@
        req->tcp = 
!GetNamedPipeInfo((HANDLE)_get_osfhandle(req->listen_socket), NULL, NULL, NULL, 
NULL);
 #endif

+#ifdef TCP_NODELAY
+       req->nodelay = 0;
+#endif
+
        fcgi_hash_init(&req->env);

        return req;
@@ -908,6 +914,18 @@
                }

                req->keep = (((fcgi_begin_request*)buf)->flags & 
FCGI_KEEP_CONN);
+#ifdef TCP_NODELAY
+               if (req->keep && req->tcp && !req->nodelay) {
+# ifdef _WIN32
+                       BOOL on = 1;
+# else
+                       int on = 1;
+# endif
+
+                       setsockopt(req->fd, IPPROTO_TCP, TCP_NODELAY, 
(char*)&on, sizeof(on));
+                       req->nodelay = 1;
+               }
+#endif
                switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + 
((fcgi_begin_request*)buf)->roleB0) {
                        case FCGI_RESPONDER:
                                fcgi_hash_set(&req->env, 
FCGI_HASH_FUNC("FCGI_ROLE", sizeof("FCGI_ROLE")-1), "FCGI_ROLE", 
sizeof("FCGI_ROLE")-1, "RESPONDER", sizeof("RESPONDER")-1);
@@ -1108,6 +1126,9 @@
                }
                close(req->fd);
 #endif
+#ifdef TCP_NODELAY
+               req->nodelay = 0;
+#endif
                req->fd = -1;
        }
 }
@@ -1158,25 +1179,34 @@
                                        FCGI_LOCK(req->listen_socket);
                                        req->fd = accept(listen_socket, (struct 
sockaddr *)&sa, &len);
                                        FCGI_UNLOCK(req->listen_socket);
-                                       if (req->fd >= 0 &&
-                                           allowed_clients &&
-                                           ((struct sockaddr *)&sa)->sa_family 
== AF_INET) {
-                                               int n = 0;
-                                               int allowed = 0;
+                                       if (req->fd >= 0) {
+                                               if (((struct sockaddr 
*)&sa)->sa_family == AF_INET) {
+#ifndef _WIN32
+                                                       req->tcp = 1;
+#endif
+                                                       if (allowed_clients) {
+                                                               int n = 0;
+                                                               int allowed = 0;

-                                               while (allowed_clients[n] != 
INADDR_NONE) {
-                                                       if (allowed_clients[n] 
== sa.sa_inet.sin_addr.s_addr) {
-                                                               allowed = 1;
-                                                               break;
+                                                               while 
(allowed_clients[n] != INADDR_NONE) {
+                                                                       if 
(allowed_clients[n] == sa.sa_inet.sin_addr.s_addr) {
+                                                                               
allowed = 1;
+                                                                               
break;
+                                                                       }
+                                                                       n++;
+                                                               }
+                                                               if (!allowed) {
+                                                                       
fprintf(stderr, "Connection from disallowed IP address '%s' is dropped.\n", 
inet_ntoa(sa.sa_inet.sin_addr));
+                                                                       
closesocket(req->fd);
+                                                                       req->fd 
= -1;
+                                                                       
continue;
+                                                               }
                                                        }
-                                                       n++;
+#ifndef _WIN32
+                                               } else {
+                                                       req->tcp = 0;
+#endif
                                                }
-                                               if (!allowed) {
-                                                       fprintf(stderr, 
"Connection from disallowed IP address '%s' is dropped.\n", 
inet_ntoa(sa.sa_inet.sin_addr));
-                                                       closesocket(req->fd);
-                                                       req->fd = -1;
-                                                       continue;
-                                               }
                                        }
                                }


-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to