httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wr...@apache.org
Subject svn commit: r584958 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS os/win32/os.h os/win32/util_win32.c server/mpm/winnt/child.c
Date Mon, 15 Oct 2007 22:49:58 GMT
Author: wrowe
Date: Mon Oct 15 15:49:57 2007
New Revision: 584958

URL: http://svn.apache.org/viewvc?rev=584958&view=rev
Log:
mpm_winnt: Eliminate wait_for_many_objects.  Allows the clean 
shutdown of the server when the MaxClients is higher then 257,
in a more responsive manner [Mladen Turk, William Rowe]

Per Mladen's +1, and that it's addressed all of Roy's concerns
with Mladen's original patch.

Modified:
    httpd/httpd/branches/2.2.x/CHANGES
    httpd/httpd/branches/2.2.x/STATUS
    httpd/httpd/branches/2.2.x/os/win32/os.h
    httpd/httpd/branches/2.2.x/os/win32/util_win32.c
    httpd/httpd/branches/2.2.x/server/mpm/winnt/child.c

Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=584958&r1=584957&r2=584958&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Mon Oct 15 15:49:57 2007
@@ -1,5 +1,9 @@
-                                                        -*- coding: utf-8 -*-
+                                                        -*- coding: utf-8 -*-
 Changes with Apache 2.2.7
+
+  *) mpm_winnt: Eliminate wait_for_many_objects.  Allows the clean 
+     shutdown of the server when the MaxClients is higher then 257,
+     in a more responsive manner [Mladen Turk, William Rowe]
 
   *) mod_proxy_http: Remove Warning headers with wrong date
      PR 16138 [Nick Kew]

Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=584958&r1=584957&r2=584958&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Mon Oct 15 15:49:57 2007
@@ -83,16 +83,6 @@
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
   [ New proposals should be added at the end of the list ]
 
-    * mpm_winnt: Eliminate wait_for_many_objects.  Allows the clean 
-      shutdown of the server when the MaxClients is higher then 257,
-      in a more responsive manner.
-      Trunk version of patch:
-        http://svn.apache.org/viewvc?view=rev&revision=573103
-        http://svn.apache.org/viewvc?view=rev&revision=573105
-      2.2.x version of patch:
-        http://people.apache.org/~wrowe/mpm_winnt_shutdown-2.2.patch
-      +1: wrowe, mturk
-
    * mod_authn_dbd: Export any additional columns queried in the SQL select
      into the environment with the name AUTHENTICATE_<COLUMN>. This brings
      mod_authn_dbd behaviour in line with mod_authnz_ldap.

Modified: httpd/httpd/branches/2.2.x/os/win32/os.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/os/win32/os.h?rev=584958&r1=584957&r2=584958&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/os/win32/os.h (original)
+++ httpd/httpd/branches/2.2.x/os/win32/os.h Mon Oct 15 15:49:57 2007
@@ -87,9 +87,6 @@
 PSECURITY_ATTRIBUTES GetNullACL();
 void CleanNullACL(void *sa);
 
-DWORD wait_for_many_objects(DWORD nCount, CONST HANDLE *lpHandles, 
-                            DWORD dwSeconds);
-
 int set_listeners_noninheritable(apr_pool_t *p);
 
 

Modified: httpd/httpd/branches/2.2.x/os/win32/util_win32.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/os/win32/util_win32.c?rev=584958&r1=584957&r2=584958&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/os/win32/util_win32.c (original)
+++ httpd/httpd/branches/2.2.x/os/win32/util_win32.c Mon Oct 15 15:49:57 2007
@@ -145,42 +145,3 @@
         LocalFree(sa);
     }
 }
-
-
-/*
- * The Win32 call WaitForMultipleObjects will only allow you to wait for
- * a maximum of MAXIMUM_WAIT_OBJECTS (current 64).  Since the threading
- * model in the multithreaded version of apache wants to use this call,
- * we are restricted to a maximum of 64 threads.  This is a simplistic
- * routine that will increase this size.
- */
-DWORD wait_for_many_objects(DWORD nCount, CONST HANDLE *lpHandles,
-                            DWORD dwSeconds)
-{
-    time_t tStopTime;
-    DWORD dwRet = WAIT_TIMEOUT;
-    DWORD dwIndex=0;
-    BOOL bFirst = TRUE;
-
-    tStopTime = time(NULL) + dwSeconds;
-
-    do {
-        if (!bFirst)
-            Sleep(1000);
-        else
-            bFirst = FALSE;
-
-        for (dwIndex = 0; dwIndex * MAXIMUM_WAIT_OBJECTS < nCount; dwIndex++) {
-            dwRet = WaitForMultipleObjects(
-                min(MAXIMUM_WAIT_OBJECTS, nCount - (dwIndex * MAXIMUM_WAIT_OBJECTS)),
-                lpHandles + (dwIndex * MAXIMUM_WAIT_OBJECTS),
-                0, 0);
-
-            if (dwRet != WAIT_TIMEOUT) {
-              break;
-            }
-        }
-    } while((time(NULL) < tStopTime) && (dwRet == WAIT_TIMEOUT));
-
-    return dwRet;
-}

Modified: httpd/httpd/branches/2.2.x/server/mpm/winnt/child.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/server/mpm/winnt/child.c?rev=584958&r1=584957&r2=584958&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/server/mpm/winnt/child.c (original)
+++ httpd/httpd/branches/2.2.x/server/mpm/winnt/child.c Mon Oct 15 15:49:57 2007
@@ -863,14 +863,15 @@
     apr_hash_t *ht;
     ap_listen_rec *lr;
     HANDLE child_events[2];
-    int threads_created = 0;
+    HANDLE *child_handles;
     int listener_started = 0;
+    int threads_created = 0;
+    int watch_thread;
+    int time_remains;
+    int cld;
     int tid;
-    HANDLE *child_handles;
     int rv;
-    time_t end_time;
     int i;
-    int cld;
 
     apr_pool_create(&pchild, pconf);
     apr_pool_tag(pchild, "pchild");
@@ -1109,21 +1110,71 @@
         apr_thread_mutex_unlock(qlock);
     }
 
-    /* Give busy worker threads a chance to service their connections */
-    ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
-                 "Child %d: Waiting for %d worker threads to exit.", my_pid, threads_created);
-    end_time = time(NULL) + 180;
-    while (threads_created) {
-        rv = wait_for_many_objects(threads_created, child_handles, (DWORD)(end_time - time(NULL)));
-        if (rv != WAIT_TIMEOUT) {
-            rv = rv - WAIT_OBJECT_0;
-            ap_assert((rv >= 0) && (rv < threads_created));
-            cleanup_thread(child_handles, &threads_created, rv);
+    /* Give busy threads a chance to service their connections,
+     * (no more than the global server timeout period which 
+     * we track in msec remaining).
+     */
+    watch_thread = 0;
+    time_remains = (int)(ap_server_conf->timeout / APR_TIME_C(1000));
+
+    while (threads_created)
+    {
+        int nFailsafe = MAXIMUM_WAIT_OBJECTS;
+        DWORD dwRet;
+
+        /* Every time we roll over to wait on the first group
+         * of MAXIMUM_WAIT_OBJECTS threads, take a breather,
+         * and infrequently update the error log.
+         */
+        if (watch_thread >= threads_created) {
+            if ((time_remains -= 100) < 0)
+                break;
+
+            /* Every 30 seconds give an update */
+            if ((time_remains % 30000) == 0) {
+                ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, 
+                             ap_server_conf,
+                             "Child %d: Waiting %d more seconds "
+                             "for %d worker threads to finish.", 
+                             my_pid, time_remains / 1000, threads_created);
+            }
+            /* We'll poll from the top, 10 times per second */
+            Sleep(100);
+            watch_thread = 0;
+        }
+
+        /* Fairness, on each iteration we will pick up with the thread
+         * after the one we just removed, even if it's a single thread.
+         * We don't block here.
+         */
+        dwRet = WaitForMultipleObjects(min(threads_created - watch_thread,
+                                           MAXIMUM_WAIT_OBJECTS),
+                                       child_handles + watch_thread, 0, 0);
+
+        if (dwRet == WAIT_FAILED) {
+            break;
+        }
+        if (dwRet == WAIT_TIMEOUT) {
+            /* none ready */
+            watch_thread += MAXIMUM_WAIT_OBJECTS;
             continue;
         }
-        break;
+        else if (dwRet >= WAIT_ABANDONED_0) {
+            /* We just got the ownership of the object, which
+             * should happen at most MAXIMUM_WAIT_OBJECTS times.
+             * It does NOT mean that the object is signaled.
+             */
+            if ((nFailsafe--) < 1)
+                break;
+        }
+        else {
+            watch_thread += (dwRet - WAIT_OBJECT_0);
+            if (watch_thread >= threads_created)
+                break;
+            cleanup_thread(child_handles, &threads_created, watch_thread);
+        }
     }
-
+ 
     /* Kill remaining threads off the hard way */
     if (threads_created) {
         ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,



Mime
View raw message