]> granicus.if.org Git - apache/commitdiff
Fix a couple of potential graceful restart bugs noted by Dean: EINTR was
authorManoj Kasichainula <manoj@apache.org>
Tue, 3 Aug 1999 23:36:43 +0000 (23:36 +0000)
committerManoj Kasichainula <manoj@apache.org>
Tue, 3 Aug 1999 23:36:43 +0000 (23:36 +0000)
never dealt with in the code to write to the pipe of death, and in
pathological cases where the number of processes is greater than
PIPE_BUF, we could end up only killing some processes.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@83563 13f79535-47bb-0310-9956-ffa450edef68

server/mpm/dexter/dexter.c
server/mpm/mpmt_pthread/mpmt_pthread.c

index 55b0c01951486a7429870426ebd185efc9a862e0..00ac1525dbfacd091519301c6bf23b2d2fcb1792 100644 (file)
@@ -1404,7 +1404,7 @@ int ap_mpm_run(pool *_pconf, pool *plog, server_rec *s)
     }
 
     if (is_graceful) {
-       int i;
+       int i, bytes_to_write;
         char char_of_death = '!';
 
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, server_conf,
@@ -1420,8 +1420,17 @@ int ap_mpm_run(pool *_pconf, pool *plog, server_rec *s)
            } 
        }
        /* give the children the signal to die */
-        if (write(pipe_of_death[1], &char_of_death, num_daemons) == -1) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "write pipe_of_death");
+        /* XXX - This while loop logic should be made into a utility function */
+        bytes_to_write = num_daemons;
+        while (bytes_to_write > 0) {
+            i = write(pipe_of_death[1], &char_of_death, bytes_to_write);
+            if (i == -1) {
+                if (errno == EINTR) continue;
+                ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,
+                             "write pipe_of_death");
+                break;
+            }
+            bytes_to_write -= i;
         }
     }
     else {
index e8cf350ab4092590767eb354bb49f9fc8c0a084c..ddb10e71b2d20999ddd551abee7e8d72f55a0d69 100644 (file)
@@ -1463,7 +1463,7 @@ int ap_mpm_run(pool *_pconf, pool *plog, server_rec *s)
     update_scoreboard_global();
 
     if (is_graceful) {
-       int i, j;
+       int i, j, bytes_to_write;
         char char_of_death = '!';
 
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, server_conf,
@@ -1472,8 +1472,17 @@ int ap_mpm_run(pool *_pconf, pool *plog, server_rec *s)
         /* give the children the signal to die. Sending more bytes than
          * children is okay, because the pipe is recreated for every
          * generation */
-        if (write(pipe_of_death[1], &char_of_death, ap_daemons_limit) == -1) {
-            ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf, "write pipe_of_death");
+        /* XXX - This while loop logic should be made into a utility function */
+        bytes_to_write = ap_daemons_limit;
+        while (bytes_to_write > 0) {
+            i = write(pipe_of_death[1], &char_of_death, bytes_to_write);
+            if (i == -1) {
+                if (errno == EINTR) continue;
+                ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf,
+                             "write pipe_of_death");
+                break;
+            }
+            bytes_to_write -= i;
         }
 
        /* This is mostly for debugging... so that we know what is still