You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Jeff Trawick (httpd)" <tr...@locus.apache.org> on 2000/06/16 22:54:23 UTC

[PATCH] reduce syscalls when setting up pipes

This is along the same general idea I mentioned earlier, but the
parmlist to ap_create_pipe() is different than I suggested then.
There are separate flags for the blocking states of the input and
output handles.

For a test with printenv and prefork and mod_cgi, the number of calls
to fcntl() associated with fiddling the blocking state of the pipes
decreased from 20 to 8 with these changes.

to-do by somebody else: 

  OS/2:   See if it will all compile.

          Check the DosCreateNPipe() parm I changed.

          Fix ap_create_pipe() to set the blocking mode of the output handle 
          properly; I can't find the right doc on the web.

  Win32:  I haven't tried to compile it yet but I will before too long.

          I haven't done a damn thing to make ap_create_pipe() set the
          blocking mode of either handle.  I can't find any existing logic
          to do that either.  I can't even find a Win32
          ap_block_pipe().  AFAICT, Win32 was broken with respect to
          the blocking mode before and it remains broken still. (no guilt here :) )

  BeOS:   See if it will all compile.

  Some cleanup to avoid syscalls is needed in the OS/2 and BeOS
  versions of ap_setprocattr_io(), probably exactly as I did in the
  Unix version.  I hesitate to change any more bytes since I can't
  compile it. 

Comments?  Do any further improvements come to mind?  Any objections?

Thanks as always!

Index: src/lib/apr/file_io/os2/pipe.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/os2/pipe.c,v
retrieving revision 1.20
diff -u -r1.20 pipe.c
--- src/lib/apr/file_io/os2/pipe.c	2000/04/28 18:27:35	1.20
+++ src/lib/apr/file_io/os2/pipe.c	2000/06/16 20:25:59
@@ -60,15 +60,22 @@
 #include <string.h>
 #include <process.h>
 
-ap_status_t ap_create_pipe(ap_file_t **in, ap_file_t **out, ap_pool_t *cont)
+/* whoops!  nothing done to get the blocking mode of the output
+ * handle set up properly!!!
+ */
+ap_status_t ap_create_pipe(ap_file_t **in, int input_blocking, 
+                           ap_file_t **out, int output_blocking, 
+                           ap_pool_t *cont)
 {
     ULONG filedes[2];
     ULONG rc, action;
+    ULONG mode;
     static int id = 0;
     char pipename[50];
 
+    mode = input_blocking ? NP_WAIT : NP_NOWAIT;
     sprintf(pipename, "/pipe/%d.%d", getpid(), id++);
-    rc = DosCreateNPipe(pipename, filedes, NP_ACCESS_INBOUND, NP_NOWAIT|1, 4096, 4096, 0);
+    rc = DosCreateNPipe(pipename, filedes, NP_ACCESS_INBOUND, mode|1, 4096, 4096, 0);
 
     if (rc)
         return APR_OS2_STATUS(rc);
Index: src/lib/apr/file_io/unix/pipe.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/unix/pipe.c,v
retrieving revision 1.33
diff -u -r1.33 pipe.c
--- src/lib/apr/file_io/unix/pipe.c	2000/06/13 19:44:16	1.33
+++ src/lib/apr/file_io/unix/pipe.c	2000/06/16 20:26:00
@@ -94,7 +94,9 @@
     return APR_EINVAL;
 }
 
-ap_status_t ap_create_pipe(ap_file_t **in, ap_file_t **out, ap_pool_t *cont)
+ap_status_t ap_create_pipe(ap_file_t **in, int input_blocking, 
+                           ap_file_t **out, int output_blocking, 
+                           ap_pool_t *cont)
 {
     int filedes[2];
 
@@ -125,8 +127,13 @@
     (*in)->thlock = NULL;
 #endif
 
-    pipenonblock(*in);
-    pipenonblock(*out);
+    if (!input_blocking) {
+        pipenonblock(*in);
+    }
+
+    if (!output_blocking) {
+        pipenonblock(*out);
+    }
 
     return APR_SUCCESS;
 }
Index: src/lib/apr/file_io/win32/pipe.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/file_io/win32/pipe.c,v
retrieving revision 1.19
diff -u -r1.19 pipe.c
--- src/lib/apr/file_io/win32/pipe.c	2000/06/15 18:54:09	1.19
+++ src/lib/apr/file_io/win32/pipe.c	2000/06/16 20:26:02
@@ -88,7 +88,9 @@
     return APR_EINVAL;
 }
 
-ap_status_t ap_create_pipe(ap_file_t **in, ap_file_t **out, ap_pool_t *cont)
+ap_status_t ap_create_pipe(ap_file_t **in, int input_blocking, 
+                           ap_file_t **out, int output_blocking,
+                           ap_pool_t *cont)
 {
     SECURITY_ATTRIBUTES sa;
 
Index: src/lib/apr/include/apr_file_io.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_file_io.h,v
retrieving revision 1.54
diff -u -r1.54 apr_file_io.h
--- src/lib/apr/include/apr_file_io.h	2000/06/15 17:39:10	1.54
+++ src/lib/apr/include/apr_file_io.h	2000/06/16 20:26:09
@@ -541,17 +541,19 @@
 
 /*
 
-=head1 ap_status_t ap_create_pipe(ap_file_t **in, ap_file_t **out, ap_pool_t *cont)
+=head1 ap_status_t ap_create_pipe(ap_file_t **in, int input_blocking, ap_file_t **out, int output_blocking, ap_pool_t *cont)
 
 B<Create an anonymous pipe.>
 
     arg 1) The file descriptor to use as input to the pipe.
-    arg 2) The file descriptor to use as output from the pipe.
-    arg 3) The pool to operate on.
+    arg 2) Flag: non-zero if you want the input end of the pipe returned in blocking mode
+    arg 3) The file descriptor to use as output from the pipe.
+    arg 4) Flag: non-zero if you want the output end of the pipe returned in blocking mode
+    arg 5) The pool to operate on.
 
 =cut
  */
-ap_status_t ap_create_pipe(ap_file_t **in, ap_file_t **out, ap_pool_t *cont);
+ap_status_t ap_create_pipe(ap_file_t **in, int input_blocking, ap_file_t **out, int output_blocking, ap_pool_t *cont);
 
 /*
 
Index: src/lib/apr/test/testpipe.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/test/testpipe.c,v
retrieving revision 1.7
diff -u -r1.7 testpipe.c
--- src/lib/apr/test/testpipe.c	2000/04/15 02:56:50	1.7
+++ src/lib/apr/test/testpipe.c	2000/06/16 20:26:38
@@ -86,7 +86,7 @@
     fprintf(stdout, "Testing pipe functions.\n");
 
     fprintf(stdout, "\tCreating pipes.......");
-    if (ap_create_pipe(&readp, &writep, context) != APR_SUCCESS) {
+    if (ap_create_pipe(&readp, 0, &writep, 0, context) != APR_SUCCESS) {
         perror("Didn't create the pipe");
         exit(-1);
     }
Index: src/lib/apr/threadproc/beos/proc.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/beos/proc.c,v
retrieving revision 1.26
diff -u -r1.26 proc.c
--- src/lib/apr/threadproc/beos/proc.c	2000/06/12 13:00:05	1.26
+++ src/lib/apr/threadproc/beos/proc.c	2000/06/16 20:26:40
@@ -86,46 +86,55 @@
 {
     ap_status_t status;
     if (in != 0) {
-        if ((status = ap_create_pipe(&attr->child_in, &attr->parent_in, 
-                                   attr->cntxt)) != APR_SUCCESS) {
+        /* TODO: put code from unix version to avoid extra syscalls playing 
+         * with the blocking state
+         */
+        if ((status = ap_create_pipe(&attr->child_in, 0, &attr->parent_in, 0,
+                                     attr->cntxt)) != APR_SUCCESS) {
             return status;
         }
         switch (in) {
         case APR_FULL_BLOCK:
             ap_block_pipe(attr->child_in);
             ap_block_pipe(attr->parent_in);
+            break;
         case APR_PARENT_BLOCK:
             ap_block_pipe(attr->parent_in);
+            break;
         case APR_CHILD_BLOCK:
             ap_block_pipe(attr->child_in);
         }
     } 
     if (out) {
-        if ((status = ap_create_pipe(&attr->parent_out, &attr->child_out, 
-                                   attr->cntxt)) != APR_SUCCESS) {
+        if ((status = ap_create_pipe(&attr->parent_out, 0, &attr->child_out, 0,
+                                     attr->cntxt)) != APR_SUCCESS) {
             return status;
         }
         switch (out) {
         case APR_FULL_BLOCK:
             ap_block_pipe(attr->child_out);
             ap_block_pipe(attr->parent_out);
+            break;
         case APR_PARENT_BLOCK:
             ap_block_pipe(attr->parent_out);
+            break;
         case APR_CHILD_BLOCK:
             ap_block_pipe(attr->child_out);
         }
     } 
     if (err) {
-        if ((status = ap_create_pipe(&attr->parent_err, &attr->child_err, 
-                                   attr->cntxt)) != APR_SUCCESS) {
+        if ((status = ap_create_pipe(&attr->parent_err, 0, &attr->child_err, 0,
+                                     attr->cntxt)) != APR_SUCCESS) {
             return status;
         }
         switch (err) {
         case APR_FULL_BLOCK:
             ap_block_pipe(attr->child_err);
             ap_block_pipe(attr->parent_err);
+            break;
         case APR_PARENT_BLOCK:
             ap_block_pipe(attr->parent_err);
+            break;
         case APR_CHILD_BLOCK:
             ap_block_pipe(attr->child_err);
         }
@@ -314,7 +323,7 @@
                                    ap_file_t *parent_in)
 {
     if (attr->child_in == NULL && attr->parent_in == NULL)
-        ap_create_pipe(&attr->child_in, &attr->parent_in, attr->cntxt);
+        ap_create_pipe(&attr->child_in, 0, &attr->parent_in, 0, attr->cntxt);
 
     if (child_in != NULL)
         ap_dupfile(&attr->child_in, child_in, attr->cntxt);
@@ -329,7 +338,7 @@
                                     ap_file_t *parent_out)
 {
     if (attr->child_out == NULL && attr->parent_out == NULL)
-        ap_create_pipe(&attr->child_out, &attr->parent_out, attr->cntxt);
+        ap_create_pipe(&attr->child_out, 0, &attr->parent_out, 0, attr->cntxt);
 
     if (child_out != NULL)
         ap_dupfile(&attr->child_out, child_out, attr->cntxt);
@@ -344,7 +353,7 @@
                                    ap_file_t *parent_err)
 {
     if (attr->child_err == NULL && attr->parent_err == NULL)
-        ap_create_pipe(&attr->child_err, &attr->parent_err, attr->cntxt);
+        ap_create_pipe(&attr->child_err, 0, &attr->parent_err, 0, attr->cntxt);
 
     if (child_err != NULL)
         ap_dupfile(&attr->child_err, child_err, attr->cntxt);
Index: src/lib/apr/threadproc/os2/proc.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/os2/proc.c,v
retrieving revision 1.24
diff -u -r1.24 proc.c
--- src/lib/apr/threadproc/os2/proc.c	2000/05/25 03:05:27	1.24
+++ src/lib/apr/threadproc/os2/proc.c	2000/06/16 20:26:42
@@ -96,8 +96,10 @@
                                  ap_int32_t out, ap_int32_t err)
 {
     ap_status_t stat;
+    int child_blocking, parent_blocking;
+
     if (in) {
-        if ((stat = ap_create_pipe(&attr->child_in, &attr->parent_in,
+        if ((stat = ap_create_pipe(&attr->child_in, 0, &attr->parent_in, 0,
                                    attr->cntxt)) != APR_SUCCESS) {
             return stat;
         }
@@ -105,14 +107,16 @@
         case APR_FULL_BLOCK:
             ap_block_pipe(attr->child_in);
             ap_block_pipe(attr->parent_in);
+            break;
         case APR_PARENT_BLOCK:
             ap_block_pipe(attr->parent_in);
+            break;
         case APR_CHILD_BLOCK:
             ap_block_pipe(attr->child_in);
         }
     } 
     if (out) {
-        if ((stat = ap_create_pipe(&attr->parent_out, &attr->child_out,
+        if ((stat = ap_create_pipe(&attr->parent_out, 0, &attr->child_out, 0,
                                    attr->cntxt)) != APR_SUCCESS) {
             return stat;
         }
@@ -120,14 +124,16 @@
         case APR_FULL_BLOCK:
             ap_block_pipe(attr->child_out);
             ap_block_pipe(attr->parent_out);
+            break;
         case APR_PARENT_BLOCK:
             ap_block_pipe(attr->parent_out);
+            break;
         case APR_CHILD_BLOCK:
             ap_block_pipe(attr->child_out);
         }
     } 
     if (err) {
-        if ((stat = ap_create_pipe(&attr->parent_err, &attr->child_err,
+        if ((stat = ap_create_pipe(&attr->parent_err, 0, &attr->child_err, 0,
                                    attr->cntxt)) != APR_SUCCESS) {
             return stat;
         }
@@ -135,8 +141,10 @@
         case APR_FULL_BLOCK:
             ap_block_pipe(attr->child_err);
             ap_block_pipe(attr->parent_err);
+            break;
         case APR_PARENT_BLOCK:
             ap_block_pipe(attr->parent_err);
+            break;
         case APR_CHILD_BLOCK:
             ap_block_pipe(attr->child_err);
         }
@@ -148,7 +156,7 @@
                                    ap_file_t *parent_in)
 {
     if (attr->child_in == NULL && attr->parent_in == NULL)
-        ap_create_pipe(&attr->child_in, &attr->parent_in, attr->cntxt);
+        ap_create_pipe(&attr->child_in, 0, &attr->parent_in, 0, attr->cntxt);
 
     if (child_in != NULL)
         ap_dupfile(&attr->child_in, child_in, attr->cntxt);
@@ -164,7 +172,7 @@
                                     ap_file_t *parent_out)
 {
     if (attr->child_out == NULL && attr->parent_out == NULL)
-        ap_create_pipe(&attr->child_out, &attr->parent_out, attr->cntxt);
+        ap_create_pipe(&attr->child_out, 0, &attr->parent_out, 0, attr->cntxt);
 
     if (child_out != NULL)
         ap_dupfile(&attr->child_out, child_out, attr->cntxt);
@@ -180,7 +188,7 @@
                                    ap_file_t *parent_err)
 {
     if (attr->child_err == NULL && attr->parent_err == NULL)
-        ap_create_pipe(&attr->child_err, &attr->parent_err, attr->cntxt);
+        ap_create_pipe(&attr->child_err, 0, &attr->parent_err, 0, attr->cntxt);
 
     if (child_err != NULL)
         ap_dupfile(&attr->child_err, child_err, attr->cntxt);
Index: src/lib/apr/threadproc/unix/proc.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/unix/proc.c,v
retrieving revision 1.30
diff -u -r1.30 proc.c
--- src/lib/apr/threadproc/unix/proc.c	2000/06/06 21:45:11	1.30
+++ src/lib/apr/threadproc/unix/proc.c	2000/06/16 20:26:43
@@ -71,50 +71,36 @@
                                  ap_int32_t out, ap_int32_t err)
 {
     ap_status_t status;
+    int child_blocking, parent_blocking;
+
     if (in != 0) {
-        if ((status = ap_create_pipe(&attr->child_in, &attr->parent_in, 
-                                   attr->cntxt)) != APR_SUCCESS) {
+        child_blocking = in == APR_FULL_BLOCK || in == APR_CHILD_BLOCK;
+        parent_blocking = in == APR_FULL_BLOCK || in == APR_PARENT_BLOCK;
+
+        if ((status = ap_create_pipe(&attr->child_in, child_blocking, 
+                                     &attr->parent_in, parent_blocking, 
+                                     attr->cntxt)) != APR_SUCCESS) {
             return status;
         }
-        switch (in) {
-        case APR_FULL_BLOCK:
-            ap_block_pipe(attr->child_in);
-            ap_block_pipe(attr->parent_in);
-        case APR_PARENT_BLOCK:
-            ap_block_pipe(attr->parent_in);
-        case APR_CHILD_BLOCK:
-            ap_block_pipe(attr->child_in);
-        }
     } 
     if (out) {
-        if ((status = ap_create_pipe(&attr->parent_out, &attr->child_out, 
-                                   attr->cntxt)) != APR_SUCCESS) {
+        child_blocking = out == APR_FULL_BLOCK || out == APR_CHILD_BLOCK;
+        parent_blocking = out == APR_FULL_BLOCK || out == APR_PARENT_BLOCK;
+
+        if ((status = ap_create_pipe(&attr->parent_out, parent_blocking,
+                                     &attr->child_out, child_blocking,
+                                     attr->cntxt)) != APR_SUCCESS) {
             return status;
         }
-        switch (out) {
-        case APR_FULL_BLOCK:
-            ap_block_pipe(attr->child_out);
-            ap_block_pipe(attr->parent_out);
-        case APR_PARENT_BLOCK:
-            ap_block_pipe(attr->parent_out);
-        case APR_CHILD_BLOCK:
-            ap_block_pipe(attr->child_out);
-        }
     } 
     if (err) {
-        if ((status = ap_create_pipe(&attr->parent_err, &attr->child_err, 
-                                   attr->cntxt)) != APR_SUCCESS) {
+        child_blocking = err == APR_FULL_BLOCK || err == APR_CHILD_BLOCK;
+        parent_blocking = err == APR_FULL_BLOCK || err == APR_PARENT_BLOCK;
+        if ((status = ap_create_pipe(&attr->parent_err, parent_blocking,
+                                     &attr->child_err, child_blocking,
+                                     attr->cntxt)) != APR_SUCCESS) {
             return status;
         }
-        switch (err) {
-        case APR_FULL_BLOCK:
-            ap_block_pipe(attr->child_err);
-            ap_block_pipe(attr->parent_err);
-        case APR_PARENT_BLOCK:
-            ap_block_pipe(attr->parent_err);
-        case APR_CHILD_BLOCK:
-            ap_block_pipe(attr->child_err);
-        }
     } 
     return APR_SUCCESS;
 }
@@ -124,7 +110,7 @@
                                    ap_file_t *parent_in)
 {
     if (attr->child_in == NULL && attr->parent_in == NULL)
-        ap_create_pipe(&attr->child_in, &attr->parent_in, attr->cntxt);
+        ap_create_pipe(&attr->child_in, 0, &attr->parent_in, 0, attr->cntxt);
 
     if (child_in != NULL)
         ap_dupfile(&attr->child_in, child_in, attr->cntxt);
@@ -140,7 +126,7 @@
                                     ap_file_t *parent_out)
 {
     if (attr->child_out == NULL && attr->parent_out == NULL)
-        ap_create_pipe(&attr->child_out, &attr->parent_out, attr->cntxt);
+        ap_create_pipe(&attr->child_out, 0, &attr->parent_out, 0, attr->cntxt);
 
     if (child_out != NULL)
         ap_dupfile(&attr->child_out, child_out, attr->cntxt);
@@ -156,7 +142,7 @@
                                    ap_file_t *parent_err)
 {
     if (attr->child_err == NULL && attr->parent_err == NULL)
-        ap_create_pipe(&attr->child_err, &attr->parent_err, attr->cntxt);
+        ap_create_pipe(&attr->child_err, 0, &attr->parent_err, 0, attr->cntxt);
 
     if (child_err != NULL)
         ap_dupfile(&attr->child_err, child_err, attr->cntxt);
Index: src/lib/apr/threadproc/win32/proc.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/threadproc/win32/proc.c,v
retrieving revision 1.31
diff -u -r1.31 proc.c
--- src/lib/apr/threadproc/win32/proc.c	2000/06/10 17:14:05	1.31
+++ src/lib/apr/threadproc/win32/proc.c	2000/06/16 20:26:44
@@ -93,19 +93,19 @@
 {
     ap_status_t stat;
     if (in) {
-        if ((stat = ap_create_pipe(&attr->child_in, &attr->parent_in, 
+        if ((stat = ap_create_pipe(&attr->child_in, 0, &attr->parent_in, 0, 
                                    attr->cntxt)) != APR_SUCCESS) {
             return stat;
         }
     }
     if (out) {
-        if ((stat = ap_create_pipe(&attr->parent_out, &attr->child_out, 
+        if ((stat = ap_create_pipe(&attr->parent_out, 0, &attr->child_out, 0,
                                    attr->cntxt)) != APR_SUCCESS) {
             return stat;
         }
     }
     if (err) {
-        if ((stat = ap_create_pipe(&attr->parent_err, &attr->child_err, 
+        if ((stat = ap_create_pipe(&attr->parent_err, 0, &attr->child_err, 0, 
                                    attr->cntxt)) != APR_SUCCESS) {
             return stat;
         }
@@ -121,7 +121,7 @@
                                     ap_file_t *parent_out)
 {
     if (attr->child_out == NULL && attr->parent_out == NULL)
-        ap_create_pipe(&attr->child_out, &attr->parent_out, attr->cntxt);
+        ap_create_pipe(&attr->child_out, 0, &attr->parent_out, 0, attr->cntxt);
 
     if (child_out != NULL)
         ap_dupfile(&attr->child_out, child_out, attr->cntxt);
@@ -135,7 +135,7 @@
                                    ap_file_t *parent_err)
 {
     if (attr->child_err == NULL && attr->parent_err == NULL)
-        ap_create_pipe(&attr->child_err, &attr->parent_err, attr->cntxt);
+        ap_create_pipe(&attr->child_err, 0, &attr->parent_err, 0, attr->cntxt);
 
     if (child_err != NULL)
         ap_dupfile(&attr->child_err, child_err, attr->cntxt);
Index: src/main/http_log.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_log.c,v
retrieving revision 1.56
diff -u -r1.56 http_log.c
--- src/main/http_log.c	2000/06/12 23:02:49	1.56
+++ src/main/http_log.c	2000/06/16 20:26:53
@@ -704,13 +704,12 @@
     pl->p = p;
     pl->program = ap_pstrdup(p, program);
     pl->pid = NULL;
-    if (ap_create_pipe(&ap_piped_log_read_fd(pl), &ap_piped_log_write_fd(pl), p) != APR_SUCCESS) {
+    if (ap_create_pipe(&ap_piped_log_read_fd(pl), 1, 
+                       &ap_piped_log_write_fd(pl), 1, p) != APR_SUCCESS) {
 	int save_errno = errno;
 	errno = save_errno;
 	return NULL;
     }
-    ap_block_pipe(ap_piped_log_read_fd(pl));
-    ap_block_pipe(ap_piped_log_write_fd(pl));
     ap_register_cleanup(p, pl, piped_log_cleanup, piped_log_cleanup_for_exec);
     if (piped_log_spawn(pl) == -1) {
 	int save_errno = errno;