Patch to mod_fastcgi to fix some problems on windows

Philip Gladstone <[email protected]>
Newsgroups gmane.comp.web.fastcgi.devel
Organization Cisco Systems, Inc
Message-ID <[email protected]>
This patch fixes a number of bugs in mod_fastcgi. In particular:

* In handling timeouts, there was confusion as to whether values were in 
milliseconds or seconds. THis has been resolved so that all timeout 
values are in milliseconds
* Fix a handle leak if we fail to connect to the server
* Add some logging for very slow server connections
* Fix a hard loop while we wait for the server to start
* Prevent starting of lots of servers at the same time while waiting for 
a server to start
* Only log the 'backoff' message once (and not in a hard loop!)
* Reduce handle inheritance somewhat to reduce the number of handles 
seen by the server processes.

-- 
Philip Gladstone                    978-ZEN-TOAD (978-936-8623)
Cisco Systems, Inc                                  Boxboro, MA

___________________________________
fastcgi-developers mailing list
http://fastcgi.com/fastcgi-developers/
fastcgi-patch7.pf (text/plain, 8.1 KB)
Index: fcgi_pm.c
===================================================================
RCS file: /raid5/cvsroot/thirdparty/apache/mod_fastcgi-2.4.2/fcgi_pm.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 fcgi_pm.c
--- fcgi_pm.c	11 May 2004 20:07:43 -0000	1.1.1.1
+++ fcgi_pm.c	5 Oct 2004 17:59:01 -0000
@@ -739,6 +739,9 @@
 
 CLEANUP:
 
+    if (process->terminationEvent)
+        SetHandleInformation(process->terminationEvent, HANDLE_FLAG_INHERIT, FALSE);
+
     if (fs->socket_path && listen_handle != INVALID_HANDLE_VALUE) 
     {
         CloseHandle(listen_handle);
@@ -1302,6 +1305,9 @@
                         continue;
                     }
                         
+                    ap_log_error(FCGI_LOG_WARN_NOERRNO, fcgi_apache_main_server,
+                        "FastCGI: scheduling start of (dynamic) server \"%s\" process: %s"
+                        , s->fs_path, (cjob->id == FCGI_REQUEST_TIMEOUT_JOB) ? "timeout job" : "start job");
                     schedule_start(s, i);
                     break;
                 }
@@ -1778,14 +1784,16 @@
 
                             if (j >= numChildren)
                             {
-                                s->bad = 1;
-                                ap_log_error(FCGI_LOG_WARN_NOERRNO, fcgi_apache_main_server,
-                                    "FastCGI:%s server \"%s\" has failed to remain"
-                                    " running for %d seconds given %d attempts, its restart"
-                                    " interval has been backed off to %d seconds",
-                                    (s->directive == APP_CLASS_DYNAMIC) ? " (dynamic)" : "",
-                                    s->fs_path, RUNTIME_SUCCESS_INTERVAL, MAX_FAILED_STARTS,
-                                    FAILED_STARTS_DELAY);
+                                if (!s->bad) {
+                                    s->bad = 1;
+                                    ap_log_error(FCGI_LOG_WARN_NOERRNO, fcgi_apache_main_server,
+                                        "FastCGI:%s server \"%s\" has failed to remain"
+                                        " running for %d seconds given %d attempts, its restart"
+                                        " interval has been backed off to %d seconds",
+                                        (s->directive == APP_CLASS_DYNAMIC) ? " (dynamic)" : "",
+                                        s->fs_path, RUNTIME_SUCCESS_INTERVAL, MAX_FAILED_STARTS,
+                                        FAILED_STARTS_DELAY);
+                                }
                             }
                             else
                             {
Index: mod_fastcgi.c
===================================================================
RCS file: /raid5/cvsroot/thirdparty/apache/mod_fastcgi-2.4.2/mod_fastcgi.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 mod_fastcgi.c
--- mod_fastcgi.c	11 May 2004 20:07:43 -0000	1.1.1.1
+++ mod_fastcgi.c	5 Oct 2004 17:59:01 -0000
@@ -1195,11 +1195,12 @@
     if (socket_path) 
     {
         BOOL ready;
-        DWORD connect_time;
+        BOOL sent_timeout_job = FALSE;
+        DWORD connect_time;     // now in ms
         int rv;
         HANDLE wait_npipe_mutex;
         DWORD interval;
-        DWORD max_connect_time = FCGI_NAMED_PIPE_CONNECT_TIMEOUT;
+        DWORD max_connect_time = FCGI_NAMED_PIPE_CONNECT_TIMEOUT * 1000;
             
         fr->using_npipe_io = TRUE;
 
@@ -1241,7 +1242,7 @@
         
         SetLastError(ERROR_SUCCESS);
         
-        rv = WaitForSingleObject(wait_npipe_mutex, max_connect_time * 1000);
+        rv = WaitForSingleObject(wait_npipe_mutex, max_connect_time);
         
         if (rv == WAIT_TIMEOUT || rv == WAIT_FAILED)
         {
@@ -1259,7 +1260,7 @@
         
         fcgi_util_ticks(&fr->queueTime);
         
-        connect_time = fr->queueTime.tv_sec - fr->startTime.tv_sec;
+        connect_time = (fr->queueTime.tv_sec - fr->startTime.tv_sec) * 1000 + (fr->queueTime.tv_usec - fr->startTime.tv_usec) / 1000;
         
         if (fr->dynamic)
         {
@@ -1267,15 +1268,16 @@
             {
                 send_to_pm(FCGI_REQUEST_TIMEOUT_JOB, fr->fs_path, fr->user, fr->group, 0, 0);
                 FCGIDBG4("connect_time=%d, interval=%d, max_connect_time=%d", connect_time, interval, max_connect_time);
+                sent_timeout_job = TRUE;
             }
-            if (max_connect_time - connect_time < interval)
+            if ((max_connect_time - connect_time) < interval)
             {
-                interval = max_connect_time - connect_time;
+                interval = (max_connect_time - connect_time);
             }
         }
         else
         {
-            interval -= connect_time * 1000;
+            interval -= connect_time;
         }
 
         for (;;)
@@ -1298,6 +1300,26 @@
                     CloseHandle(wait_npipe_mutex);
                     fcgi_util_ticks(&fr->queueTime);
                     FCGIDBG2("got npipe connect: %s", fr->fs_path);
+#if 1
+                    {
+                        static unsigned int max_seen_connect;
+                        static unsigned int last_reset;
+                        
+                        if (fr->queueTime.tv_sec - last_reset > 3600) {
+                            max_seen_connect >>= 1;
+                            last_reset = fr->queueTime.tv_sec;
+                        }
+
+                        connect_time = (fr->queueTime.tv_sec - fr->startTime.tv_sec) * 1000 + (fr->queueTime.tv_usec - fr->startTime.tv_usec) / 1000;
+
+                        if (connect_time > max_seen_connect + 100) {
+                            max_seen_connect = connect_time;
+
+                            ap_log_rerror(FCGI_LOG_ERR_NOERRNO, r, "FastCGI: Time to connect to server \"%s\" was %d milleseconds", fr->fs_path, connect_time);
+                        }
+                    }
+#endif
+
                     return FCGI_OK;
                 }
 
@@ -1313,14 +1335,15 @@
                 FCGIDBG2("missed npipe connect: %s", fr->fs_path);
             }
         
-            if (fr->dynamic) 
+            if (fr->dynamic && !sent_timeout_job) 
             {
                 send_to_pm(FCGI_REQUEST_TIMEOUT_JOB, fr->fs_path, fr->user, fr->group, 0, 0);
+                sent_timeout_job = TRUE;
             }
 
             fcgi_util_ticks(&fr->queueTime);
 
-            connect_time = fr->queueTime.tv_sec - fr->startTime.tv_sec;
+            connect_time = (fr->queueTime.tv_sec - fr->startTime.tv_sec) * 1000 + (fr->queueTime.tv_usec - fr->startTime.tv_usec) / 1000;
 
             FCGIDBG5("interval=%d, max_connect_time=%d, connect_time=%d, ready=%d", interval, max_connect_time, connect_time, ready);
 
@@ -1331,6 +1354,7 @@
                     "CreateFile()/WaitNamedPipe() timed out", fr->fs_path);
                 break;
             }
+            Sleep(1000);    /* Prevent hard loop waiting for server to start */
         }
 
         ReleaseMutex(wait_npipe_mutex);
@@ -1614,6 +1638,8 @@
 
     ap_hard_timeout("FastCGI request processing", r);
 
+    dynamic_first_recv = 0; // Turn all this junk off
+
     while (state != STATE_CLIENT_SEND)
     {
         DWORD msec_timeout;
@@ -1655,6 +1681,8 @@
                 if (open_connection_to_fs(fr) != FCGI_OK) 
                 {
                     ap_kill_timeout(r);
+                    CloseHandle(events[0]);
+                    CloseHandle(events[1]);
                     return HTTP_INTERNAL_SERVER_ERROR;
                 }
 
@@ -1815,7 +1843,11 @@
             else 
             {
                 /* Killed time somewhere.. client read? */
-                send_to_pm(FCGI_REQUEST_TIMEOUT_JOB, fr->fs_path, fr->user, fr->group, 0, 0);
+				/* We only want to say that this job times out the *first* time that
+                 * we record a timeout
+                 */
+                if (dynamic_first_recv <= 1)
+	                send_to_pm(FCGI_REQUEST_TIMEOUT_JOB, fr->fs_path, fr->user, fr->group, 0, 0);
                 dynamic_first_recv = qwait.tv_sec / dynamicPleaseStartDelay + 1;
                 timeout.tv_sec = dynamic_first_recv * dynamicPleaseStartDelay;
                 timeout.tv_usec = 100000;  /* fudge for select() slop */
smime.p7s (application/x-pkcs7-signature, 3.2 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.