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;