You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ko...@apache.org on 2017/07/11 16:51:09 UTC

svn commit: r1801637 - /httpd/httpd/trunk/server/mpm/winnt/child.c

Author: kotkov
Date: Tue Jul 11 16:51:09 2017
New Revision: 1801637

URL: http://svn.apache.org/viewvc?rev=1801637&view=rev
Log:
mpm_winnt: Simplify the shutdown code that was waiting for multiple worker
thread handles in batches.

Starting from r1801636, there is no difference between ending the wait with
one or multiple remaining threads.  This is because we terminate the process
if at least one thread is still active when we hit a timeout.

Therefore, instead of making an effort to evenly distribute and batch the
handles with WaitForMultipleObjects(), we could just start from one end,
and wait for one thread handle at a time.

Modified:
    httpd/httpd/trunk/server/mpm/winnt/child.c

Modified: httpd/httpd/trunk/server/mpm/winnt/child.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/winnt/child.c?rev=1801637&r1=1801636&r2=1801637&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/winnt/child.c (original)
+++ httpd/httpd/trunk/server/mpm/winnt/child.c Tue Jul 11 16:51:09 2017
@@ -841,18 +841,6 @@ static DWORD __stdcall worker_main(void
 }
 
 
-static void cleanup_thread(HANDLE *handles, int *thread_cnt,
-                           int thread_to_clean)
-{
-    int i;
-
-    CloseHandle(handles[thread_to_clean]);
-    for (i = thread_to_clean; i < ((*thread_cnt) - 1); i++)
-        handles[i] = handles[i + 1];
-    (*thread_cnt)--;
-}
-
-
 /*
  * child_main()
  * Entry point for the main control thread for the child process.
@@ -904,7 +892,6 @@ void child_main(apr_pool_t *pconf, DWORD
     HANDLE *child_handles;
     int listener_started = 0;
     int threads_created = 0;
-    int watch_thread;
     int time_remains;
     int cld;
     DWORD tid;
@@ -1199,64 +1186,35 @@ void child_main(apr_pool_t *pconf, DWORD
      * (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;
+        HANDLE handle = child_handles[threads_created - 1];
         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, APLOGNO(00362)
-                             "Child: Waiting %d more seconds "
-                             "for %d worker threads to finish.",
-                             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) {
+        if (time_remains < 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, APLOGNO(00362)
+                         "Child: Waiting %d more seconds "
+                         "for %d worker threads to finish.",
+                         time_remains / 1000, threads_created);
         }
+
+        dwRet = WaitForSingleObject(handle, 100);
+        time_remains -= 100;
         if (dwRet == WAIT_TIMEOUT) {
-            /* none ready */
-            watch_thread += MAXIMUM_WAIT_OBJECTS;
-            continue;
-        }
-        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;
+            /* Keep waiting */
+        }
+        else if (dwRet == WAIT_OBJECT_0) {
+            CloseHandle(handle);
+            threads_created--;
         }
         else {
-            watch_thread += (dwRet - WAIT_OBJECT_0);
-            if (watch_thread >= threads_created)
-                break;
-            cleanup_thread(child_handles, &threads_created, watch_thread);
+            break;
         }
     }