diff options
author | Benedikt Boehm <hollow@gentoo.org> | 2011-02-18 17:28:28 +0000 |
---|---|---|
committer | Benedikt Boehm <hollow@gentoo.org> | 2011-02-18 17:28:28 +0000 |
commit | d6cb8f21b2f5723b4fc1d12a34f9551324684e73 (patch) | |
tree | ebc362205629065b06462363c5ceda12c58fb3dc | |
parent | Add patch for APXS to respect LDFLAGS, see bug #335405. (diff) | |
download | apache-d6cb8f21b2f5723b4fc1d12a34f9551324684e73.tar.gz apache-d6cb8f21b2f5723b4fc1d12a34f9551324684e73.tar.bz2 apache-d6cb8f21b2f5723b4fc1d12a34f9551324684e73.zip |
fix bugs in init scripts and include latest peruser patch
-rw-r--r-- | 2.2/init/apache2.confd | 1 | ||||
-rwxr-xr-x | 2.2/init/apache2.initd | 12 | ||||
-rw-r--r-- | 2.2/patches/20_all_peruser_0.4.0-rc2.patch (renamed from 2.2/patches/20_all_peruser_0.4.0-rc1.patch) | 3303 |
3 files changed, 1721 insertions, 1595 deletions
diff --git a/2.2/init/apache2.confd b/2.2/init/apache2.confd index c3cb9fd..4635201 100644 --- a/2.2/init/apache2.confd +++ b/2.2/init/apache2.confd @@ -19,6 +19,7 @@ # MEM_CACHE Enables default configuration mod_mem_cache # PROXY Enables mod_proxy # SSL Enables SSL (available if USE=ssl) +# STATUS Enabled mod_status, a useful module for statistics # SUEXEC Enables running CGI scripts (in USERDIR) through suexec. # USERDIR Enables /~username mapping to /home/username/public_html # diff --git a/2.2/init/apache2.initd b/2.2/init/apache2.initd index ec0fa1c..56f4391 100755 --- a/2.2/init/apache2.initd +++ b/2.2/init/apache2.initd @@ -4,6 +4,16 @@ opts="configdump configtest fullstatus graceful gracefulstop modules reload virtualhosts" +description_configdump="Dumps the configuration of the apache server. Requires lynx and server-info to be enabled." +description_configtest="Run syntax tests for configuration files only." +description_fullstatus="Gives the full status of the server. Requires lynx and server-status to be enabled." +description_graceful="A graceful restart advises the children to exit after the current request and reloads the configuration." +description_gracefulstop="A graceful stop advises the children to exit after the current request and stops the server." +description_modules="Dump a list of loaded Static and Shared Modules." +description_reload="Kills all children and reloads the configuration." +description_virtualhosts="Show the settings as parsed from the config file (currently only shows the virtualhost settings)." +description_stop="Kills all children and stops the server." + depend() { need net use mysql dns logger netmount postgresql @@ -66,7 +76,7 @@ start() { sleep 1 && i=$(expr $i + 1) done - test $i -le ${TIMEOUT} + test -e "${PIDFILE}" eend $? } diff --git a/2.2/patches/20_all_peruser_0.4.0-rc1.patch b/2.2/patches/20_all_peruser_0.4.0-rc2.patch index 782bab5..3ad18bc 100644 --- a/2.2/patches/20_all_peruser_0.4.0-rc1.patch +++ b/2.2/patches/20_all_peruser_0.4.0-rc2.patch @@ -1,39 +1,19 @@ -diff -ruN httpd-2.2.14/docs/conf/extra/httpd-mpm.conf.in peruser-0.4rc1/docs/conf/extra/httpd-mpm.conf.in ---- httpd-2.2.14/docs/conf/extra/httpd-mpm.conf.in 2007-12-29 04:08:28.000000000 +0100 -+++ peruser-0.4rc1/docs/conf/extra/httpd-mpm.conf.in 2009-11-21 21:38:45.000000000 +0100 -@@ -27,6 +27,24 @@ - # active mpm. - # +diff -Nur httpd-2.2.16/modules/generators/mod_status.c httpd-2.2.16-peruser/modules/generators/mod_status.c +--- httpd-2.2.16/modules/generators/mod_status.c 2008-01-02 11:43:52.000000000 +0200 ++++ httpd-2.2.16-peruser/modules/generators/mod_status.c 2010-08-16 11:35:17.202107000 +0300 +@@ -201,10 +201,11 @@ -+# peruser MPM -+# IdleTimeout: maximum time before a child is killed after being idle, 0 to disable -+# ExpireTimeout: maximum time a child can live, 0 to disable -+# MinSpareProcessors: minimum number of idle children, to handle request spikes -+# MaxProcessors: Maximum number of processors per vhost -+# ServerLimit: maximum value of MaxClients for this run of Apache -+# MaxClients: maximum number of children alive at the same time -+# MaxMultiplexers: maximum number of multiplexers the server can have -+<IfModule mpm_peruser_module> -+ IdleTimeout 900 -+ ExpireTimeout 1800 -+ MinSpareProcessors 2 -+ MaxProcessors 10 -+ ServerLimit 256 -+ MaxClients 256 -+ MaxMultiplexers 20 -+</IfModule> -+ - # prefork MPM - # StartServers: number of server processes to start - # MinSpareServers: minimum number of server processes which are kept spare -diff -ruN httpd-2.2.14/modules/generators/mod_status.c peruser-0.4rc1/modules/generators/mod_status.c ---- httpd-2.2.14/modules/generators/mod_status.c 2008-01-02 10:43:52.000000000 +0100 -+++ peruser-0.4rc1/modules/generators/mod_status.c 2009-11-21 21:07:28.000000000 +0100 -@@ -205,6 +205,7 @@ - #define STAT_OPT_REFRESH 0 - #define STAT_OPT_NOTABLE 1 - #define STAT_OPT_AUTO 2 -+#define STAT_OPT_STATS 3 + /* ID values for command table */ + +-#define STAT_OPT_END -1 +-#define STAT_OPT_REFRESH 0 +-#define STAT_OPT_NOTABLE 1 +-#define STAT_OPT_AUTO 2 ++#define STAT_OPT_END -1 ++#define STAT_OPT_REFRESH 0 ++#define STAT_OPT_NOTABLE 1 ++#define STAT_OPT_AUTO 2 ++#define STAT_OPT_PERUSER_STATS 3 struct stat_opt { int id; @@ -41,7 +21,7 @@ diff -ruN httpd-2.2.14/modules/generators/mod_status.c peruser-0.4rc1/modules/ge {STAT_OPT_REFRESH, "refresh", "Refresh"}, {STAT_OPT_NOTABLE, "notable", NULL}, {STAT_OPT_AUTO, "auto", NULL}, -+ {STAT_OPT_STATS, "stats", NULL}, ++ {STAT_OPT_PERUSER_STATS, "peruser_stats", NULL}, {STAT_OPT_END, NULL, NULL} }; @@ -49,26 +29,24 @@ diff -ruN httpd-2.2.14/modules/generators/mod_status.c peruser-0.4rc1/modules/ge #endif int short_report; int no_table_report; -+ int stats_report; ++ int peruser_stats; worker_score *ws_record; process_score *ps_record; char *stat_buffer; -@@ -268,7 +271,8 @@ +@@ -268,6 +271,7 @@ kbcount = 0; short_report = 0; no_table_report = 0; -- -+ stats_report=0; -+ ++ peruser_stats=0; + pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t)); stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char)); - @@ -312,6 +316,9 @@ case STAT_OPT_NOTABLE: no_table_report = 1; break; -+ case STAT_OPT_STATS: -+ stats_report = 1; ++ case STAT_OPT_PERUSER_STATS: ++ peruser_stats = 1; + break; case STAT_OPT_AUTO: ap_set_content_type(r, "text/plain; charset=ISO-8859-1"); @@ -79,24 +57,30 @@ diff -ruN httpd-2.2.14/modules/generators/mod_status.c peruser-0.4rc1/modules/ge (no_table_report ? AP_STATUS_NOTABLE : 0) | - (ap_extended_status ? AP_STATUS_EXTENDED : 0); + (ap_extended_status ? AP_STATUS_EXTENDED : 0) | -+ (stats_report ? AP_STATUS_STATS : 0); ++ (peruser_stats ? AP_STATUS_PERUSER_STATS : 0); ap_run_status_hook(r, flags); } -diff -ruN httpd-2.2.14/modules/generators/mod_status.h peruser-0.4rc1/modules/generators/mod_status.h ---- httpd-2.2.14/modules/generators/mod_status.h 2006-07-12 05:38:44.000000000 +0200 -+++ peruser-0.4rc1/modules/generators/mod_status.h 2009-11-21 21:07:28.000000000 +0100 -@@ -32,6 +32,7 @@ - #define AP_STATUS_SHORT (0x1) /* short, non-HTML report requested */ - #define AP_STATUS_NOTABLE (0x2) /* HTML report without tables */ - #define AP_STATUS_EXTENDED (0x4) /* detailed report */ -+#define AP_STATUS_STATS (0x8) /* extended user statistics report */ +diff -Nur httpd-2.2.16/modules/generators/mod_status.h httpd-2.2.16-peruser/modules/generators/mod_status.h +--- httpd-2.2.16/modules/generators/mod_status.h 2006-07-12 06:38:44.000000000 +0300 ++++ httpd-2.2.16-peruser/modules/generators/mod_status.h 2010-08-16 11:35:17.202107000 +0300 +@@ -29,9 +29,10 @@ + #include "ap_config.h" + #include "httpd.h" + +-#define AP_STATUS_SHORT (0x1) /* short, non-HTML report requested */ +-#define AP_STATUS_NOTABLE (0x2) /* HTML report without tables */ +-#define AP_STATUS_EXTENDED (0x4) /* detailed report */ ++#define AP_STATUS_SHORT (0x1) /* short, non-HTML report requested */ ++#define AP_STATUS_NOTABLE (0x2) /* HTML report without tables */ ++#define AP_STATUS_EXTENDED (0x4) /* detailed report */ ++#define AP_STATUS_PERUSER_STATS (0x8) /* peruser mpm extended status */ #if !defined(WIN32) #define STATUS_DECLARE(type) type -diff -ruN httpd-2.2.14/modules/ssl/mod_ssl.h peruser-0.4rc1/modules/ssl/mod_ssl.h ---- httpd-2.2.14/modules/ssl/mod_ssl.h 2006-07-12 05:38:44.000000000 +0200 -+++ peruser-0.4rc1/modules/ssl/mod_ssl.h 2009-11-21 14:29:17.000000000 +0100 +diff -Nur httpd-2.2.16/modules/ssl/mod_ssl.h httpd-2.2.16-peruser/modules/ssl/mod_ssl.h +--- httpd-2.2.16/modules/ssl/mod_ssl.h 2006-07-12 06:38:44.000000000 +0300 ++++ httpd-2.2.16-peruser/modules/ssl/mod_ssl.h 2009-09-01 16:19:22.425377000 +0300 @@ -50,6 +50,10 @@ * is using SSL/TLS. */ APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); @@ -108,9 +92,9 @@ diff -ruN httpd-2.2.14/modules/ssl/mod_ssl.h peruser-0.4rc1/modules/ssl/mod_ssl. /** The ssl_proxy_enable() and ssl_engine_disable() optional functions * are used by mod_proxy to enable use of SSL for outgoing * connections. */ -diff -ruN httpd-2.2.14/modules/ssl/ssl_engine_vars.c peruser-0.4rc1/modules/ssl/ssl_engine_vars.c ---- httpd-2.2.14/modules/ssl/ssl_engine_vars.c 2009-09-06 13:19:05.000000000 +0200 -+++ peruser-0.4rc1/modules/ssl/ssl_engine_vars.c 2009-11-21 14:33:56.000000000 +0100 +diff -Nur httpd-2.2.16/modules/ssl/ssl_engine_vars.c httpd-2.2.16-peruser/modules/ssl/ssl_engine_vars.c +--- httpd-2.2.16/modules/ssl/ssl_engine_vars.c 2010-02-27 23:00:58.000000000 +0200 ++++ httpd-2.2.16-peruser/modules/ssl/ssl_engine_vars.c 2010-03-16 15:59:55.641979000 +0200 @@ -58,6 +58,12 @@ return sslconn && sslconn->ssl; } @@ -132,9 +116,9 @@ diff -ruN httpd-2.2.14/modules/ssl/ssl_engine_vars.c peruser-0.4rc1/modules/ssl/ APR_REGISTER_OPTIONAL_FN(ssl_var_lookup); APR_REGISTER_OPTIONAL_FN(ssl_ext_lookup); -diff -ruN httpd-2.2.14/server/mpm/config.m4 peruser-0.4rc1/server/mpm/config.m4 ---- httpd-2.2.14/server/mpm/config.m4 2005-10-30 18:05:26.000000000 +0100 -+++ peruser-0.4rc1/server/mpm/config.m4 2009-11-21 14:29:17.000000000 +0100 +diff -Nur httpd-2.2.16/server/mpm/config.m4 httpd-2.2.16-peruser/server/mpm/config.m4 +--- httpd-2.2.16/server/mpm/config.m4 2005-10-30 19:05:26.000000000 +0200 ++++ httpd-2.2.16-peruser/server/mpm/config.m4 2009-09-01 16:19:22.425377000 +0300 @@ -1,7 +1,7 @@ AC_MSG_CHECKING(which MPM to use) AC_ARG_WITH(mpm, @@ -153,9 +137,9 @@ diff -ruN httpd-2.2.14/server/mpm/config.m4 peruser-0.4rc1/server/mpm/config.m4 return 0 else return 1 -diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/AUTHORS peruser-0.4rc1/server/mpm/experimental/peruser/AUTHORS ---- httpd-2.2.14/server/mpm/experimental/peruser/AUTHORS 1970-01-01 01:00:00.000000000 +0100 -+++ peruser-0.4rc1/server/mpm/experimental/peruser/AUTHORS 2009-11-21 14:29:17.000000000 +0100 +diff -Nur httpd-2.2.16/server/mpm/experimental/peruser/AUTHORS httpd-2.2.16-peruser/server/mpm/experimental/peruser/AUTHORS +--- httpd-2.2.16/server/mpm/experimental/peruser/AUTHORS 1970-01-01 03:00:00.000000000 +0300 ++++ httpd-2.2.16-peruser/server/mpm/experimental/peruser/AUTHORS 2009-09-01 16:19:22.425377000 +0300 @@ -0,0 +1,11 @@ +Enrico Weigelt <weigelt [at] metux.de> (MetuxMPM maintainer) +Sean Gabriel Heacock <gabriel [at] telana.com> (Peruser maintainer) @@ -168,136 +152,25 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/AUTHORS peruser-0.4rc1/se +Steve Amerige <mpm [at] fatbear.com> +Stefan Klingner <stefan.klingner [at] mephisto23.com> (Peruser maintainer) +Michal Grzedzicki <lazy404 [at] gmail.com> -diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/Makefile.in peruser-0.4rc1/server/mpm/experimental/peruser/Makefile.in ---- httpd-2.2.14/server/mpm/experimental/peruser/Makefile.in 1970-01-01 01:00:00.000000000 +0100 -+++ peruser-0.4rc1/server/mpm/experimental/peruser/Makefile.in 2009-11-21 14:29:17.000000000 +0100 -@@ -0,0 +1,5 @@ -+ -+LTLIBRARY_NAME = libperuser.la -+LTLIBRARY_SOURCES = peruser.c -+ -+include $(top_srcdir)/build/ltlib.mk -diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/config.m4 peruser-0.4rc1/server/mpm/experimental/peruser/config.m4 ---- httpd-2.2.14/server/mpm/experimental/peruser/config.m4 1970-01-01 01:00:00.000000000 +0100 -+++ peruser-0.4rc1/server/mpm/experimental/peruser/config.m4 2009-11-21 14:29:17.000000000 +0100 +diff -Nur httpd-2.2.16/server/mpm/experimental/peruser/config.m4 httpd-2.2.16-peruser/server/mpm/experimental/peruser/config.m4 +--- httpd-2.2.16/server/mpm/experimental/peruser/config.m4 1970-01-01 03:00:00.000000000 +0300 ++++ httpd-2.2.16-peruser/server/mpm/experimental/peruser/config.m4 2009-09-01 16:19:22.425377000 +0300 @@ -0,0 +1,3 @@ +if test "$MPM_NAME" = "peruser" ; then + APACHE_FAST_OUTPUT(server/mpm/experimental/$MPM_NAME/Makefile) +fi -diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/mpm.h peruser-0.4rc1/server/mpm/experimental/peruser/mpm.h ---- httpd-2.2.14/server/mpm/experimental/peruser/mpm.h 1970-01-01 01:00:00.000000000 +0100 -+++ peruser-0.4rc1/server/mpm/experimental/peruser/mpm.h 2009-11-21 21:10:39.000000000 +0100 -@@ -0,0 +1,107 @@ -+/* ==================================================================== -+ * The Apache Software License, Version 1.1 -+ * -+ * Copyright (c) 2000-2003 The Apache Software Foundation. All rights -+ * reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * 3. The end-user documentation included with the redistribution, -+ * if any, must include the following acknowledgment: -+ * "This product includes software developed by the -+ * Apache Software Foundation (http://www.apache.org/)." -+ * Alternately, this acknowledgment may appear in the software itself, -+ * if and wherever such third-party acknowledgments normally appear. -+ * -+ * 4. The names "Apache" and "Apache Software Foundation" must -+ * not be used to endorse or promote products derived from this -+ * software without prior written permission. For written -+ * permission, please contact apache@apache.org. -+ * -+ * 5. Products derived from this software may not be called "Apache", -+ * nor may "Apache" appear in their name, without prior written -+ * permission of the Apache Software Foundation. -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * ==================================================================== -+ * -+ * This software consists of voluntary contributions made by many -+ * individuals on behalf of the Apache Software Foundation. For more -+ * information on the Apache Software Foundation, please see -+ * <http://www.apache.org/>. -+ * -+ * Portions of this software are based upon public domain software -+ * originally written at the National Center for Supercomputing Applications, -+ * University of Illinois, Urbana-Champaign. -+ */ -+ -+#include "httpd.h" -+#include "mpm_default.h" -+#include "scoreboard.h" -+#include "unixd.h" -+ -+#ifndef APACHE_MPM_PERUSER_H -+#define APACHE_MPM_PERUSER_H -+ -+#define PERUSER_MPM -+ -+#define MPM_NAME "Peruser" -+ -+#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES -+#define AP_MPM_WANT_WAIT_OR_TIMEOUT -+#define AP_MPM_WANT_PROCESS_CHILD_STATUS -+#define AP_MPM_WANT_SET_PIDFILE -+#define AP_MPM_WANT_SET_SCOREBOARD -+#define AP_MPM_WANT_SET_LOCKFILE -+#define AP_MPM_WANT_SET_MAX_REQUESTS -+#define AP_MPM_WANT_SET_COREDUMPDIR -+#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH -+#define AP_MPM_WANT_SIGNAL_SERVER -+#define AP_MPM_WANT_SET_MAX_MEM_FREE -+#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK -+ -+#define AP_MPM_USES_POD 1 -+#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) -+#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) -+#define MPM_VALID_PID(p) (getpgid(p) == getpgrp()) -+#define MPM_ACCEPT_FUNC unixd_accept -+ -+extern int ap_threads_per_child; -+extern int ap_max_daemons_limit; -+extern server_rec *ap_server_conf; -+ -+/* Table of child status */ -+#define SERVER_DEAD 0 -+#define SERVER_DYING 1 -+#define SERVER_ALIVE 2 -+ -+typedef struct ap_ctable { -+ pid_t pid; -+ unsigned char status; -+} ap_ctable; -+ -+static const char* child_clone(); +diff -Nur httpd-2.2.16/server/mpm/experimental/peruser/Makefile.in httpd-2.2.16-peruser/server/mpm/experimental/peruser/Makefile.in +--- httpd-2.2.16/server/mpm/experimental/peruser/Makefile.in 1970-01-01 03:00:00.000000000 +0300 ++++ httpd-2.2.16-peruser/server/mpm/experimental/peruser/Makefile.in 2009-09-01 16:19:22.425377000 +0300 +@@ -0,0 +1,5 @@ + ++LTLIBRARY_NAME = libperuser.la ++LTLIBRARY_SOURCES = peruser.c + -+#endif /* APACHE_MPM_PERUSER_H */ -diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/mpm_default.h peruser-0.4rc1/server/mpm/experimental/peruser/mpm_default.h ---- httpd-2.2.14/server/mpm/experimental/peruser/mpm_default.h 1970-01-01 01:00:00.000000000 +0100 -+++ peruser-0.4rc1/server/mpm/experimental/peruser/mpm_default.h 2009-11-21 14:29:17.000000000 +0100 ++include $(top_srcdir)/build/ltlib.mk +diff -Nur httpd-2.2.16/server/mpm/experimental/peruser/mpm_default.h httpd-2.2.16-peruser/server/mpm/experimental/peruser/mpm_default.h +--- httpd-2.2.16/server/mpm/experimental/peruser/mpm_default.h 1970-01-01 03:00:00.000000000 +0300 ++++ httpd-2.2.16-peruser/server/mpm/experimental/peruser/mpm_default.h 2009-09-01 16:19:22.425377000 +0300 @@ -0,0 +1,162 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 @@ -461,11 +334,116 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/mpm_default.h peruser-0.4 +#endif + +#endif /* AP_MPM_DEFAULT_H */ -diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/server/mpm/experimental/peruser/peruser.c ---- httpd-2.2.14/server/mpm/experimental/peruser/peruser.c 1970-01-01 01:00:00.000000000 +0100 -+++ peruser-0.4rc1/server/mpm/experimental/peruser/peruser.c 2009-11-21 22:02:27.000000000 +0100 -@@ -0,0 +1,3979 @@ +diff -Nur httpd-2.2.16/server/mpm/experimental/peruser/mpm.h httpd-2.2.16-peruser/server/mpm/experimental/peruser/mpm.h +--- httpd-2.2.16/server/mpm/experimental/peruser/mpm.h 1970-01-01 03:00:00.000000000 +0300 ++++ httpd-2.2.16-peruser/server/mpm/experimental/peruser/mpm.h 2010-08-06 09:27:22.994976000 +0300 +@@ -0,0 +1,102 @@ ++/* ==================================================================== ++ * The Apache Software License, Version 1.1 ++ * ++ * Copyright (c) 2000-2003 The Apache Software Foundation. All rights ++ * reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. The end-user documentation included with the redistribution, ++ * if any, must include the following acknowledgment: ++ * "This product includes software developed by the ++ * Apache Software Foundation (http://www.apache.org/)." ++ * Alternately, this acknowledgment may appear in the software itself, ++ * if and wherever such third-party acknowledgments normally appear. ++ * ++ * 4. The names "Apache" and "Apache Software Foundation" must ++ * not be used to endorse or promote products derived from this ++ * software without prior written permission. For written ++ * permission, please contact apache@apache.org. ++ * ++ * 5. Products derived from this software may not be called "Apache", ++ * nor may "Apache" appear in their name, without prior written ++ * permission of the Apache Software Foundation. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ++ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ++ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This software consists of voluntary contributions made by many ++ * individuals on behalf of the Apache Software Foundation. For more ++ * information on the Apache Software Foundation, please see ++ * <http://www.apache.org/>. ++ * ++ * Portions of this software are based upon public domain software ++ * originally written at the National Center for Supercomputing Applications, ++ * University of Illinois, Urbana-Champaign. ++ */ + ++#include "httpd.h" ++#include "mpm_default.h" ++#include "scoreboard.h" ++#include "unixd.h" ++ ++#ifndef APACHE_MPM_PERUSER_H ++#define APACHE_MPM_PERUSER_H ++ ++#define PERUSER_MPM ++ ++#define MPM_NAME "Peruser" ++ ++#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES ++#define AP_MPM_WANT_WAIT_OR_TIMEOUT ++#define AP_MPM_WANT_PROCESS_CHILD_STATUS ++#define AP_MPM_WANT_SET_PIDFILE ++#define AP_MPM_WANT_SET_SCOREBOARD ++#define AP_MPM_WANT_SET_LOCKFILE ++#define AP_MPM_WANT_SET_MAX_REQUESTS ++#define AP_MPM_WANT_SET_COREDUMPDIR ++#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH ++#define AP_MPM_WANT_SIGNAL_SERVER ++#define AP_MPM_WANT_SET_MAX_MEM_FREE ++#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK ++ ++#define AP_MPM_USES_POD 1 ++#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) ++#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) ++#define MPM_VALID_PID(p) (getpgid(p) == getpgrp()) ++#define MPM_ACCEPT_FUNC unixd_accept ++ ++extern int ap_threads_per_child; ++extern int ap_max_daemons_limit; ++extern server_rec *ap_server_conf; ++ ++/* Table of child status */ ++#define SERVER_DEAD 0 ++#define SERVER_DYING 1 ++#define SERVER_ALIVE 2 ++ ++static const char* child_clone(); ++ ++ ++#endif /* APACHE_MPM_PERUSER_H */ +diff -Nur httpd-2.2.16/server/mpm/experimental/peruser/peruser.c httpd-2.2.16-peruser/server/mpm/experimental/peruser/peruser.c +--- httpd-2.2.16/server/mpm/experimental/peruser/peruser.c 1970-01-01 03:00:00.000000000 +0300 ++++ httpd-2.2.16-peruser/server/mpm/experimental/peruser/peruser.c 2010-08-16 11:35:17.202107000 +0300 +@@ -0,0 +1,4115 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * @@ -588,7 +566,6 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +#error "Peruser MPM requres shared memory support." +#endif + -+ +/* should be APR-ized */ +#include <grp.h> +#include <pwd.h> @@ -599,7 +576,6 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +#include <signal.h> +#include <sys/times.h> + -+ +#ifdef MPM_PERUSER_DEBUG +# define _DBG(text,par...) \ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, \ @@ -629,7 +605,6 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +#define AP_PERUSER_THISCHILD -1 +#define AP_PERUSER_OTHERCHILD -2 + -+ +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. @@ -673,20 +648,20 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +/* config globals */ + -+int ap_threads_per_child=0; /* Worker threads per child */ ++int ap_threads_per_child = 0; /* Worker threads per child */ +static apr_proc_mutex_t *accept_mutex; -+static int ap_min_processors=DEFAULT_MIN_PROCESSORS; -+static int ap_min_free_processors=DEFAULT_MIN_FREE_PROCESSORS; -+static int ap_max_free_processors=DEFAULT_MAX_FREE_PROCESSORS; -+static int ap_max_processors=DEFAULT_MAX_PROCESSORS; -+static int ap_min_multiplexers=DEFAULT_MIN_MULTIPLEXERS; -+static int ap_max_multiplexers=DEFAULT_MAX_MULTIPLEXERS; -+static int ap_daemons_limit=0; /* MaxClients */ -+static int expire_timeout=DEFAULT_EXPIRE_TIMEOUT; -+static int idle_timeout=DEFAULT_IDLE_TIMEOUT; -+static int multiplexer_idle_timeout=DEFAULT_MULTIPLEXER_IDLE_TIMEOUT; -+static int processor_wait_timeout=DEFAULT_PROCESSOR_WAIT_TIMEOUT; -+static int processor_wait_steps=DEFAULT_PROCESSOR_WAIT_STEPS; ++static int ap_min_processors = DEFAULT_MIN_PROCESSORS; ++static int ap_min_free_processors = DEFAULT_MIN_FREE_PROCESSORS; ++static int ap_max_free_processors = DEFAULT_MAX_FREE_PROCESSORS; ++static int ap_max_processors = DEFAULT_MAX_PROCESSORS; ++static int ap_min_multiplexers = DEFAULT_MIN_MULTIPLEXERS; ++static int ap_max_multiplexers = DEFAULT_MAX_MULTIPLEXERS; ++static int ap_daemons_limit = 0; /* MaxClients */ ++static int expire_timeout = DEFAULT_EXPIRE_TIMEOUT; ++static int idle_timeout = DEFAULT_IDLE_TIMEOUT; ++static int multiplexer_idle_timeout = DEFAULT_MULTIPLEXER_IDLE_TIMEOUT; ++static int processor_wait_timeout = DEFAULT_PROCESSOR_WAIT_TIMEOUT; ++static int processor_wait_steps = DEFAULT_PROCESSOR_WAIT_STEPS; +static int server_limit = DEFAULT_SERVER_LIMIT; +static int first_server_limit; +static int changed_limit_at_restart; @@ -700,11 +675,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +{ + int processor_id; + -+ const char *name; /* Server environment's unique string identifier */ ++ const char *name; /* Server environment's unique string identifier */ + + /* security settings */ -+ uid_t uid; /* user id */ -+ gid_t gid; /* group id */ ++ uid_t uid; /* user id */ ++ gid_t gid; /* group id */ + const char *chroot; /* directory to chroot() to, can be null */ + short nice_lvl; + const char *cgroup; /* cgroup directory, can be null */ @@ -717,13 +692,18 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + short availability; + + /* sockets */ -+ int input; /* The socket descriptor */ -+ int output; /* The socket descriptor */ ++ int input; /* The socket descriptor */ ++ int output; /* The socket descriptor */ + + /* error flags */ + /* we use these to reduce log clutter (report only on first failure) */ + short error_cgroup; /* When writing pid to cgroup fails */ -+ short error_pass; /* When unable to pass request to the processor (eg all workers busy) */ ++ short error_pass; /* When unable to pass request to the processor */ ++ ++ /* statistics */ ++ unsigned long stats_requests; /* requests handled */ ++ unsigned long stats_connections; /* connections handled */ ++ unsigned long stats_dropped; /* connections dropped because multiplexer was not able to pass */ +} server_env_t; + +typedef struct @@ -737,13 +717,12 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + server_env_t *table; +} server_env; + -+ +typedef struct +{ + /* identification */ -+ int id; /* index in child_info_table */ -+ pid_t pid; /* process id */ -+ int status; /* status of child */ ++ int id; /* index in child_info_table */ ++ pid_t pid; /* process id */ ++ int status; /* status of child */ + int type; /* multiplexer or processor */ + server_env_t *senv; + @@ -756,16 +735,6 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +typedef struct +{ -+ /* identification */ -+ int id; /* index in child_info_table */ -+ pid_t pid; /* process id */ -+ int status; /* status of child */ -+ int type; /* multiplexer or processor */ -+ apr_time_t last_used; -+} child_grace_info_t; -+ -+typedef struct -+{ + apr_size_t num; +} child_info_control; + @@ -781,22 +750,18 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + short missing_senv_reported; +} peruser_server_conf; + -+ +typedef struct peruser_header +{ + char *headers; + apr_pool_t *p; +} peruser_header; + -+ +/* Tables used to determine the user and group each child process should + * run as. The hash table is used to correlate a server name with a child + * process. + */ +static apr_size_t child_info_size; +static child_info *child_info_image = NULL; -+static child_grace_info_t *child_grace_info_table; -+struct ap_ctable *ap_child_table; + +#define NUM_CHILDS (child_info_image != NULL ? child_info_image->control->num : 0) +#define CHILD_INFO_TABLE (child_info_image != NULL ? child_info_image->table : NULL) @@ -811,16 +776,10 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +#ifndef WIN32 +static /* but must be exported to mpm_winnt */ +#endif -+ apr_shm_t *child_info_shm = NULL; -+ apr_shm_t *server_env_shm = NULL; ++apr_shm_t *child_info_shm = NULL; ++apr_shm_t *server_env_shm = NULL; +#endif + -+/* -+ * The max child slot ever assigned, preserved across restarts. Necessary -+ * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We -+ * use this value to optimize routines that have to scan the entire scoreboard. -+ */ -+int ap_max_daemons_limit = -1; +server_rec *ap_server_conf; + +module AP_MODULE_DECLARE_DATA mpm_peruser_module; @@ -829,7 +788,6 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +static apr_file_t *pipe_of_death_in = NULL; +static apr_file_t *pipe_of_death_out = NULL; + -+ +/* one_process --- debugging mode variable; can be set from the command line + * with the -X flag. If set, this gets you the child_main loop running + * in the process which originally started up (no detach, no make_child), @@ -843,13 +801,13 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +static int one_process = 0; + -+static apr_pool_t *pconf; /* Pool for config stuff */ -+static apr_pool_t *pchild; /* Pool for httpd child stuff */ ++static apr_pool_t *pconf; /* Pool for config stuff */ ++static apr_pool_t *pchild; /* Pool for httpd child stuff */ + -+static pid_t ap_my_pid; /* it seems silly to call getpid all the time */ ++static pid_t ap_my_pid; /* it seems silly to call getpid all the time */ +static pid_t parent_pid; +static int my_child_num; -+ap_generation_t volatile ap_my_generation=0; ++ap_generation_t volatile ap_my_generation = 0; + +#ifdef TPF +int tpf_child = 0; @@ -858,12 +816,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +static int die_now = 0; + -+int grace_children = 0; -+int grace_children_alive = 0; +int server_env_cleanup = 1; +const char *multiplexer_chroot = NULL; ++server_env_t *multiplexer_senv; + -+// function added to mod_ssl and exported (there was nothing useful for us in the current api) ++/* function added to mod_ssl and exported (there was nothing useful for us) */ +typedef int (*ssl_server_is_https_t)(server_rec*); +ssl_server_is_https_t ssl_server_is_https = NULL; + @@ -876,28 +833,28 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + */ +static void chdir_for_gprof(void) +{ -+ core_server_config *sconf = -+ ap_get_module_config(ap_server_conf->module_config, &core_module); ++ core_server_config *sconf = ++ ap_get_module_config(ap_server_conf->module_config, &core_module); + char *dir = sconf->gprof_dir; + const char *use_dir; + + if(dir) { + apr_status_t res; -+ char buf[512]; -+ int len = strlen(sconf->gprof_dir) - 1; -+ if(*(dir + len) == '%') { -+ dir[len] = '\0'; -+ apr_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid()); -+ } -+ use_dir = ap_server_root_relative(pconf, buf[0] ? buf : dir); -+ res = apr_dir_make(use_dir, 0755, pconf); -+ if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf, -+ "gprof: error creating directory %s", dir); -+ } ++ char buf[512]; ++ int len = strlen(sconf->gprof_dir) - 1; ++ if(*(dir + len) == '%') { ++ dir[len] = '\0'; ++ apr_snprintf(buf, sizeof(buf), "%sgprof.%d", dir, (int)getpid()); ++ } ++ use_dir = ap_server_root_relative(pconf, buf[0] ? buf : dir); ++ res = apr_dir_make(use_dir, 0755, pconf); ++ if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, errno, ap_server_conf, ++ "gprof: error creating directory %s", dir); ++ } + } + else { -+ use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR); ++ use_dir = ap_server_root_relative(pconf, DEFAULT_REL_RUNTIMEDIR); + } + + chdir(use_dir); @@ -908,11 +865,13 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +char* child_type_string(int type) +{ -+ switch(type) -+ { -+ case CHILD_TYPE_MULTIPLEXER: return "MULTIPLEXER"; -+ case CHILD_TYPE_PROCESSOR: return "PROCESSOR"; -+ case CHILD_TYPE_WORKER: return "WORKER"; ++ switch (type) { ++ case CHILD_TYPE_MULTIPLEXER: ++ return "MULTIPLEXER"; ++ case CHILD_TYPE_PROCESSOR: ++ return "PROCESSOR"; ++ case CHILD_TYPE_WORKER: ++ return "WORKER"; + } + + return "UNKNOWN"; @@ -920,32 +879,47 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +char* child_status_string(int status) +{ -+ switch(status) -+ { -+ case CHILD_STATUS_STANDBY: return "STANDBY"; -+ case CHILD_STATUS_STARTING: return "STARTING"; -+ case CHILD_STATUS_READY: return "READY"; -+ case CHILD_STATUS_ACTIVE: return "ACTIVE"; -+ case CHILD_STATUS_RESTART: return "RESTART"; ++ switch (status) { ++ case CHILD_STATUS_STANDBY: ++ return "STANDBY"; ++ case CHILD_STATUS_STARTING: ++ return "STARTING"; ++ case CHILD_STATUS_READY: ++ return "READY"; ++ case CHILD_STATUS_ACTIVE: ++ return "ACTIVE"; ++ case CHILD_STATUS_RESTART: ++ return "RESTART"; + } + + return "UNKNOWN"; +} + -+char* scoreboard_status_string(int status) { -+ switch(status) -+ { -+ case SERVER_DEAD: return "DEAD"; -+ case SERVER_STARTING: return "STARTING"; -+ case SERVER_READY: return "READY"; -+ case SERVER_BUSY_READ: return "BUSY_READ"; -+ case SERVER_BUSY_WRITE: return "BUSY_WRITE"; -+ case SERVER_BUSY_KEEPALIVE: return "BUSY_KEEPALIVE"; -+ case SERVER_BUSY_LOG: return "BUSY_LOG"; -+ case SERVER_BUSY_DNS: return "BUSY_DNS"; -+ case SERVER_CLOSING: return "CLOSING"; -+ case SERVER_GRACEFUL: return "GRACEFUL"; -+ case SERVER_NUM_STATUS: return "NUM_STATUS"; ++char* scoreboard_status_string(int status) ++{ ++ switch (status) { ++ case SERVER_DEAD: ++ return "DEAD"; ++ case SERVER_STARTING: ++ return "STARTING"; ++ case SERVER_READY: ++ return "READY"; ++ case SERVER_BUSY_READ: ++ return "BUSY_READ"; ++ case SERVER_BUSY_WRITE: ++ return "BUSY_WRITE"; ++ case SERVER_BUSY_KEEPALIVE: ++ return "BUSY_KEEPALIVE"; ++ case SERVER_BUSY_LOG: ++ return "BUSY_LOG"; ++ case SERVER_BUSY_DNS: ++ return "BUSY_DNS"; ++ case SERVER_CLOSING: ++ return "CLOSING"; ++ case SERVER_GRACEFUL: ++ return "GRACEFUL"; ++ case SERVER_NUM_STATUS: ++ return "NUM_STATUS"; + } + + return "UNKNOWN"; @@ -954,43 +928,44 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +void dump_child_table() +{ +#ifdef MPM_PERUSER_DEBUG -+ int x; -+ server_env_t *senv; -+ -+ _DBG("%-3s %-5s %-8s %-12s %-4s %-4s %-25s %5s %6s %7s", -+ "ID", "PID", "STATUS", "TYPE", "UID", "GID", "CHROOT", "INPUT", "OUTPUT", "SOCK_FD"); -+ -+ for(x = 0; x < NUM_CHILDS; x++) -+ { -+ senv = CHILD_INFO_TABLE[x].senv; -+ _DBG("%-3d %-5d %-8s %-12s %-4d %-4d %-25s %-5d %-6d %-7d", -+ CHILD_INFO_TABLE[x].id, -+ CHILD_INFO_TABLE[x].pid, -+ child_status_string(CHILD_INFO_TABLE[x].status), -+ child_type_string(CHILD_INFO_TABLE[x].type), -+ senv == NULL ? -1 : senv->uid, -+ senv == NULL ? -1 : senv->gid, -+ senv == NULL ? NULL : senv->chroot, -+ senv == NULL ? -1 : CHILD_INFO_TABLE[x].senv->input, -+ senv == NULL ? -1 : CHILD_INFO_TABLE[x].senv->output, -+ CHILD_INFO_TABLE[x].sock_fd); -+ } ++ int x; ++ server_env_t *senv; ++ ++ _DBG("%-3s %-5s %-8s %-12s %-4s %-4s %-25s %5s %6s %7s", ++ "ID", "PID", "STATUS", "TYPE", "UID", "GID", "CHROOT", "INPUT", ++ "OUTPUT", "SOCK_FD"); ++ ++ for(x = 0; x < NUM_CHILDS; x++) ++ { ++ senv = CHILD_INFO_TABLE[x].senv; ++ _DBG("%-3d %-5d %-8s %-12s %-4d %-4d %-25s %-5d %-6d %-7d", ++ CHILD_INFO_TABLE[x].id, ++ CHILD_INFO_TABLE[x].pid, ++ child_status_string(CHILD_INFO_TABLE[x].status), ++ child_type_string(CHILD_INFO_TABLE[x].type), ++ senv == NULL ? -1 : senv->uid, ++ senv == NULL ? -1 : senv->gid, ++ senv == NULL ? NULL : senv->chroot, ++ senv == NULL ? -1 : CHILD_INFO_TABLE[x].senv->input, ++ senv == NULL ? -1 : CHILD_INFO_TABLE[x].senv->output, ++ CHILD_INFO_TABLE[x].sock_fd); ++ } +#endif +} + +void dump_server_env_image() +{ +#ifdef MPM_PERUSER_DEBUG -+ int x; -+ _DBG("%-3s %-7s %-7s %-7s", "N", "INPUT", "OUTPUT", "CHROOT"); -+ for(x = 0; x < NUM_SENV; x++) -+ { -+ _DBG("%-3d %-7d %-7d %-7s", x, SENV[x].input, SENV[x].output, SENV[x].chroot); -+ } ++ int x; ++ _DBG("%-3s %-7s %-7s %-7s", "N", "INPUT", "OUTPUT", "CHROOT"); ++ for(x = 0; x < NUM_SENV; x++) ++ { ++ _DBG("%-3d %-7d %-7d %-7s", x, SENV[x].input, SENV[x].output, ++ SENV[x].chroot); ++ } +#endif +} + -+ +/* XXX - I don't know if TPF will ever use this module or not, so leave + * the ap_check_signals calls in but disable them - manoj */ +#define ap_check_signals() @@ -1003,20 +978,20 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + mpm_state = AP_MPMQ_STOPPING; + -+ if (CHILD_INFO_TABLE[my_child_num].type != CHILD_TYPE_MULTIPLEXER && -+ CHILD_INFO_TABLE[my_child_num].senv) ++ if (CHILD_INFO_TABLE[my_child_num].type != CHILD_TYPE_MULTIPLEXER ++ && CHILD_INFO_TABLE[my_child_num].senv) + { -+ retval = close(CHILD_INFO_TABLE[my_child_num].senv->input); -+ _DBG("close(CHILD_INFO_TABLE[%d].senv->input) = %d", -+ my_child_num, retval); ++ retval = close(CHILD_INFO_TABLE[my_child_num].senv->input); ++ _DBG("close(CHILD_INFO_TABLE[%d].senv->input) = %d", ++ my_child_num, retval); + -+ retval = close(CHILD_INFO_TABLE[my_child_num].senv->output); -+ _DBG("close(CHILD_INFO_TABLE[%d].senv->output) = %d", -+ my_child_num, retval); ++ retval = close(CHILD_INFO_TABLE[my_child_num].senv->output); ++ _DBG("close(CHILD_INFO_TABLE[%d].senv->output) = %d", ++ my_child_num, retval); + } + + if (pchild) { -+ apr_pool_destroy(pchild); ++ apr_pool_destroy(pchild); + } + ap_mpm_pod_close(pod); + chdir_for_gprof(); @@ -1029,8 +1004,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + if (rv != APR_SUCCESS) { + const char *msg = "couldn't grab the accept mutex"; + -+ if (ap_my_generation != -+ ap_scoreboard_image->global->running_generation) { ++ if (ap_my_generation != ap_scoreboard_image->global->running_generation) ++ { + ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, msg); + clean_child_exit(0); + } @@ -1047,8 +1022,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + if (rv != APR_SUCCESS) { + const char *msg = "couldn't release the accept mutex"; + -+ if (ap_my_generation != -+ ap_scoreboard_image->global->running_generation) { ++ if (ap_my_generation != ap_scoreboard_image->global->running_generation) ++ { + ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, msg); + /* don't exit here... we have a connection to + * process, after which point we'll see that the @@ -1075,65 +1050,65 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ -+ switch(query_code){ -+ case AP_MPMQ_MAX_DAEMON_USED: -+ *result = ap_daemons_limit; -+ return APR_SUCCESS; -+ case AP_MPMQ_IS_THREADED: -+ *result = AP_MPMQ_NOT_SUPPORTED; -+ return APR_SUCCESS; -+ case AP_MPMQ_IS_FORKED: -+ *result = AP_MPMQ_DYNAMIC; -+ return APR_SUCCESS; -+ case AP_MPMQ_HARD_LIMIT_DAEMONS: -+ *result = server_limit; -+ return APR_SUCCESS; -+ case AP_MPMQ_HARD_LIMIT_THREADS: -+ *result = HARD_THREAD_LIMIT; -+ return APR_SUCCESS; -+ case AP_MPMQ_MAX_THREADS: -+ *result = 0; -+ return APR_SUCCESS; -+ case AP_MPMQ_MIN_SPARE_DAEMONS: -+ *result = ap_min_free_processors; -+ return APR_SUCCESS; -+ case AP_MPMQ_MIN_SPARE_THREADS: -+ *result = 0; -+ return APR_SUCCESS; -+ case AP_MPMQ_MAX_SPARE_THREADS: -+ *result = 0; -+ return APR_SUCCESS; -+ case AP_MPMQ_MAX_REQUESTS_DAEMON: -+ *result = ap_max_requests_per_child; -+ return APR_SUCCESS; -+ case AP_MPMQ_MAX_DAEMONS: -+ *result = server_limit; -+ return APR_SUCCESS; -+ case AP_MPMQ_MPM_STATE: -+ *result = mpm_state; -+ return APR_SUCCESS; ++ switch (query_code) { ++ case AP_MPMQ_MAX_DAEMON_USED: ++ *result = ap_daemons_limit; ++ return APR_SUCCESS; ++ case AP_MPMQ_IS_THREADED: ++ *result = AP_MPMQ_NOT_SUPPORTED; ++ return APR_SUCCESS; ++ case AP_MPMQ_IS_FORKED: ++ *result = AP_MPMQ_DYNAMIC; ++ return APR_SUCCESS; ++ case AP_MPMQ_HARD_LIMIT_DAEMONS: ++ *result = server_limit; ++ return APR_SUCCESS; ++ case AP_MPMQ_HARD_LIMIT_THREADS: ++ *result = HARD_THREAD_LIMIT; ++ return APR_SUCCESS; ++ case AP_MPMQ_MAX_THREADS: ++ *result = 0; ++ return APR_SUCCESS; ++ case AP_MPMQ_MIN_SPARE_DAEMONS: ++ *result = ap_min_free_processors; ++ return APR_SUCCESS; ++ case AP_MPMQ_MIN_SPARE_THREADS: ++ *result = 0; ++ return APR_SUCCESS; ++ case AP_MPMQ_MAX_SPARE_THREADS: ++ *result = 0; ++ return APR_SUCCESS; ++ case AP_MPMQ_MAX_REQUESTS_DAEMON: ++ *result = ap_max_requests_per_child; ++ return APR_SUCCESS; ++ case AP_MPMQ_MAX_DAEMONS: ++ *result = server_limit; ++ return APR_SUCCESS; ++ case AP_MPMQ_MPM_STATE: ++ *result = mpm_state; ++ return APR_SUCCESS; + } + return APR_ENOTIMPL; +} + +#if defined(NEED_WAITPID) +/* -+ Systems without a real waitpid sometimes lose a child's exit while waiting -+ for another. Search through the scoreboard for missing children. ++ Systems without a real waitpid sometimes lose a child's exit while waiting ++ for another. Search through the scoreboard for missing children. + */ +int reap_children(int *exitcode, apr_exit_why_e *status) +{ + int n, pid; + -+ for (n = 0; n < ap_max_daemons_limit; ++n) { -+ if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && -+ kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { -+ ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); -+ /* just mark it as having a successful exit status */ ++ for (n = 0; n < NUM_CHILDS; ++n) { ++ if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && ++ kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { ++ ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); ++ /* just mark it as having a successful exit status */ + *status = APR_PROC_EXIT; + *exitcode = 0; -+ return(pid); -+ } ++ return(pid); ++ } + } + return 0; +} @@ -1146,9 +1121,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + retval = chdir(ap_coredump_dir); + apr_signal(sig, SIG_DFL); + if (ap_my_pid == parent_pid) { -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, -+ 0, ap_server_conf, -+ "seg fault or similar nasty error detected " ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, ++ "seg fault or similar nasty error detected " + "in the parent process"); + } + kill(getpid(), sig); @@ -1167,7 +1141,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +static void just_die(int sig) +{ -+_DBG("function called"); ++ _DBG("function called"); + clean_child_exit(0); +} + @@ -1180,11 +1154,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +static void sig_term(int sig) +{ + if (shutdown_pending == 1) { -+ /* Um, is this _probably_ not an error, if the user has -+ * tried to do a shutdown twice quickly, so we won't -+ * worry about reporting it. -+ */ -+ return; ++ /* Um, is this _probably_ not an error, if the user has ++ * tried to do a shutdown twice quickly, so we won't ++ * worry about reporting it. ++ */ ++ return; + } + shutdown_pending = 1; +} @@ -1195,20 +1169,16 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +static void restart(int sig) +{ + if (restart_pending == 1) { -+ /* Probably not an error - don't bother reporting it */ -+ return; ++ /* Probably not an error - don't bother reporting it */ ++ return; + } + restart_pending = 1; + is_graceful = (sig == AP_SIG_GRACEFUL); +} + +/* Sets die_now if we received a character on the pipe_of_death */ -+static apr_status_t check_pipe_of_death -+( -+ void **csd, -+ ap_listen_rec *lr, -+ apr_pool_t *ptrans -+) ++static apr_status_t check_pipe_of_death(void **csd, ap_listen_rec *lr, ++ apr_pool_t *ptrans) +{ + int ret; + char pipe_read_char; @@ -1216,24 +1186,22 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + _DBG("WATCH: die_now=%d", die_now); + -+ if (die_now) return APR_SUCCESS; ++ if (die_now) ++ return APR_SUCCESS; + + /* apr_thread_mutex_lock(pipe_of_death_mutex); */ + ret = apr_socket_recv(lr->sd, &pipe_read_char, &n); -+ if (APR_STATUS_IS_EAGAIN(ret)) -+ { -+ /* It lost the lottery. It must continue to suffer -+ * through a life of servitude. */ -+ _DBG("POD read EAGAIN"); -+ return ret; ++ if (APR_STATUS_IS_EAGAIN(ret)) { ++ /* It lost the lottery. It must continue to suffer ++ * through a life of servitude. */ ++ _DBG("POD read EAGAIN"); ++ return ret; + } -+ else -+ { -+ if (pipe_read_char != AP_PERUSER_CHAR_OF_DEATH) -+ { -+ _DBG("got wrong char %c", pipe_read_char); -+ return APR_SUCCESS; -+ } ++ else { ++ if (pipe_read_char != AP_PERUSER_CHAR_OF_DEATH) { ++ _DBG("got wrong char %c", pipe_read_char); ++ return APR_SUCCESS; ++ } + /* It won the lottery (or something else is very + * wrong). Embrace death with open arms. */ + die_now = 1; @@ -1252,53 +1220,63 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + sa.sa_flags = 0; + + if (!one_process) { -+ sa.sa_handler = sig_coredump; ++ sa.sa_handler = sig_coredump; +#if defined(SA_ONESHOT) -+ sa.sa_flags = SA_ONESHOT; ++ sa.sa_flags = SA_ONESHOT; +#elif defined(SA_RESETHAND) -+ sa.sa_flags = SA_RESETHAND; ++ sa.sa_flags = SA_RESETHAND; +#endif -+ if (sigaction(SIGSEGV, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGSEGV)"); ++ if (sigaction(SIGSEGV, &sa, NULL) < 0) ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGSEGV)"); +#ifdef SIGBUS -+ if (sigaction(SIGBUS, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGBUS)"); ++ if (sigaction(SIGBUS, &sa, NULL) < 0) ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGBUS)"); +#endif +#ifdef SIGABORT -+ if (sigaction(SIGABORT, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABORT)"); ++ if (sigaction(SIGABORT, &sa, NULL) < 0) ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGABORT)"); +#endif +#ifdef SIGABRT -+ if (sigaction(SIGABRT, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGABRT)"); ++ if (sigaction(SIGABRT, &sa, NULL) < 0) ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGABRT)"); +#endif +#ifdef SIGILL -+ if (sigaction(SIGILL, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGILL)"); ++ if (sigaction(SIGILL, &sa, NULL) < 0) ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGILL)"); +#endif -+ sa.sa_flags = 0; ++ sa.sa_flags = 0; + } + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGTERM)"); +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ + sa.sa_handler = SIG_IGN; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGXFSZ)"); +#endif +#ifdef SIGPIPE + sa.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy @@ -1307,29 +1285,31 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { -+ apr_signal(SIGSEGV, sig_coredump); ++ apr_signal(SIGSEGV, sig_coredump); +#ifdef SIGBUS -+ apr_signal(SIGBUS, sig_coredump); ++ apr_signal(SIGBUS, sig_coredump); +#endif /* SIGBUS */ +#ifdef SIGABORT -+ apr_signal(SIGABORT, sig_coredump); ++ apr_signal(SIGABORT, sig_coredump); +#endif /* SIGABORT */ +#ifdef SIGABRT -+ apr_signal(SIGABRT, sig_coredump); ++ apr_signal(SIGABRT, sig_coredump); +#endif /* SIGABRT */ +#ifdef SIGILL -+ apr_signal(SIGILL, sig_coredump); ++ apr_signal(SIGILL, sig_coredump); +#endif /* SIGILL */ +#ifdef SIGXCPU -+ apr_signal(SIGXCPU, SIG_DFL); ++ apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ -+ apr_signal(SIGXFSZ, SIG_DFL); ++ apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + @@ -1363,14 +1343,12 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return 0; +} + -+ +static int total_processors(int child_num) +{ + int i, total; + -+ for(i = 0, total = 0; i < NUM_CHILDS; ++i) -+ { -+ if(CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv) ++ for (i = 0, total = 0; i < NUM_CHILDS; ++i) { ++ if (CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv) + total++; + } + @@ -1381,10 +1359,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +{ + int i, total; + -+ for(i = 0, total = 0; i < NUM_CHILDS; ++i) -+ { -+ if( (CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv) && (CHILD_INFO_TABLE[i].pid > 0 ) ) ++ for (i = 0, total = 0; i < NUM_CHILDS; ++i) { ++ if (CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv ++ && CHILD_INFO_TABLE[i].pid > 0) { + total++; ++ } + } + + return total; @@ -1394,13 +1373,15 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +{ + int i, total; + -+ if(env_num >= NUM_SENV) -+ return -1; ++ if (env_num >= NUM_SENV) { ++ return -1; ++ } + -+ for(i = 0, total = 0; i < NUM_CHILDS; ++i) -+ { -+ if((CHILD_INFO_TABLE[i].senv == &SENV[env_num]) && (CHILD_INFO_TABLE[i].pid > 0)) ++ for (i = 0, total = 0; i < NUM_CHILDS; ++i) { ++ if (CHILD_INFO_TABLE[i].senv == &SENV[env_num] ++ && CHILD_INFO_TABLE[i].pid > 0) { + total++; ++ } + } + + return total; @@ -1410,11 +1391,10 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +{ + int i, total; + -+ for(i = 0, total = 0; i < NUM_CHILDS; ++i) -+ { -+ if(CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv && -+ (CHILD_INFO_TABLE[i].status == CHILD_STATUS_READY)) -+ { ++ for (i = 0, total = 0; i < NUM_CHILDS; ++i) { ++ if (CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv ++ && (CHILD_INFO_TABLE[i].status == CHILD_STATUS_READY ++ || CHILD_INFO_TABLE[i].status == CHILD_STATUS_STARTING)) { + total++; + } + } @@ -1426,69 +1406,77 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +{ + int i, total; + -+ for(i = 0, total = 0; i < NUM_CHILDS; ++i) -+ { -+ if(CHILD_INFO_TABLE[i].senv == &SENV[env_num] && (CHILD_INFO_TABLE[i].status == CHILD_STATUS_READY) ) ++ for (i = 0, total = 0; i < NUM_CHILDS; ++i) { ++ if (CHILD_INFO_TABLE[i].senv == &SENV[env_num] ++ && (CHILD_INFO_TABLE[i].status == CHILD_STATUS_READY ++ || CHILD_INFO_TABLE[i].status == CHILD_STATUS_STARTING)) { + total++; ++ } + } + + return total; +} + -+ -+static int wait_for_workers(child_info_t *processor) { ++static int wait_for_workers(child_info_t *processor) ++{ + int i, wait_step_size, wait_time; -+ ++ + wait_step_size = 100 / processor_wait_steps; + + /* Check if the processor is available */ -+ if (total_processors(processor->id) == processor->senv->max_processors && -+ idle_processors(processor->id) == 0 && processor_wait_timeout > 0) { ++ if (total_processors(processor->id) == processor->senv->max_processors ++ && idle_processors(processor->id) == 0 && processor_wait_timeout > 0) { ++ + /* The processor is currently busy, try to wait (a little) */ + _DBG("processor seems to be busy, trying to wait for it"); + + if (processor->senv->availability == 0) { + processor->senv->availability = 0; + -+ _DBG("processor is very busy (availability = 0) - not passing request"); ++ _DBG("processor is busy (availability = 0) - not passing request"); + + if (processor->senv->error_pass == 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, -+ "Too many requests for processor %s, increase MaxProcessors", processor->senv->name); ++ "Too many requests for processor %s, " ++ "increase MaxProcessors", processor->senv->name); + } -+ ++ + /* No point in waiting for the processor, it's very busy */ + return -1; + } -+ -+ /* We sleep a little (depending how available the processor usually is) */ ++ ++ /* We sleep a little (depending how available the processor is) */ + wait_time = (processor_wait_timeout / processor_wait_steps) * 1000000; + -+ for(i = 0; i <= processor->senv->availability; i += wait_step_size) { ++ for (i = 0; i <= processor->senv->availability; i += wait_step_size) { + usleep(wait_time); + + /* Check if the processor is ready */ -+ if (total_processors(processor->id) < processor->senv->max_processors || -+ idle_processors(processor->id) > 0) { ++ if (total_processors(processor->id) ++ < processor->senv->max_processors ++ || idle_processors(processor->id) > 0) ++ { + /* The processor has freed - lets use it */ + _DBG("processor freed before wait time expired"); + break; + } + } -+ ++ + if (processor->senv->availability <= wait_step_size) { + processor->senv->availability = 0; + } -+ else processor->senv->availability -= wait_step_size; -+ ++ else ++ processor->senv->availability -= wait_step_size; ++ + /* Check if we waited all the time */ + if (i > processor->senv->availability) { + _DBG("processor is busy - not passing request (availability = %d)", -+ processor->senv->availability); ++ processor->senv->availability); + + if (processor->senv->error_pass == 0) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, -+ "Too many requests for processor %s, increase MaxProcessors", processor->senv->name); ++ "Too many requests for processor %s, " ++ "increase MaxProcessors", processor->senv->name); + } + + return -1; @@ -1500,10 +1488,12 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + else { + /* Smoothly increment the availability back to 100 */ -+ if (processor->senv->availability >= 100-wait_step_size) { ++ if (processor->senv->availability >= 100 - wait_step_size) { + processor->senv->availability = 100; + } -+ else processor->senv->availability += wait_step_size; ++ else { ++ processor->senv->availability += wait_step_size; ++ } + } + + return 0; @@ -1515,7 +1505,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + * a socket or a whole request by inspecting the header_length of the + * message. If it is zero then only a socket was sent. + */ -+static int pass_socket(apr_socket_t *thesock, child_info_t *processor, apr_pool_t *pool) ++static int pass_socket(apr_socket_t *thesock, child_info_t *processor, ++ apr_pool_t *pool) +{ + int rv; + struct msghdr msg; @@ -1528,63 +1519,64 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + apr_size_t body_len = 0; + peruser_header h; + -+ if (!processor) -+ { ++ if (!processor) { + _DBG("server %s in child %d has no child_info associated", -+ "(unkonwn)", my_child_num); ++ "(unknown)", my_child_num); + return -1; + } -+ ++ + /* Make sure there are free workers on the other end */ -+ if (wait_for_workers(processor) == -1) return -1; ++ if (wait_for_workers(processor) == -1) { ++ return -1; ++ } + + _DBG("passing request to another child.", 0); + + apr_os_sock_get(&sock_fd, thesock); ++ + /* passing remote_addr too, see comments below */ + apr_socket_addr_get(&remote_addr, APR_REMOTE, thesock); -+ ++ + header_len = 0; + body_len = 0; + + iov[0].iov_base = &header_len; -+ iov[0].iov_len = sizeof(header_len); ++ iov[0].iov_len = sizeof(header_len); + iov[1].iov_base = &body_len; -+ iov[1].iov_len = sizeof(body_len); ++ iov[1].iov_len = sizeof(body_len); + iov[2].iov_base = remote_addr; -+ iov[2].iov_len = sizeof(*remote_addr); ++ iov[2].iov_len = sizeof(*remote_addr); + iov[3].iov_base = h.headers; -+ iov[3].iov_len = 0; ++ iov[3].iov_len = 0; + iov[4].iov_base = body; -+ iov[4].iov_len = body_len; ++ iov[4].iov_len = body_len; + -+ msg.msg_name = NULL; ++ msg.msg_name = NULL; + msg.msg_namelen = 0; -+ msg.msg_iov = iov; -+ msg.msg_iovlen = 5; ++ msg.msg_iov = iov; ++ msg.msg_iovlen = 5; + + cmsg = apr_palloc(pool, sizeof(*cmsg) + sizeof(sock_fd)); -+ cmsg->cmsg_len = CMSG_LEN(sizeof(sock_fd)); ++ cmsg->cmsg_len = CMSG_LEN(sizeof(sock_fd)); + cmsg->cmsg_level = SOL_SOCKET; -+ cmsg->cmsg_type = SCM_RIGHTS; ++ cmsg->cmsg_type = SCM_RIGHTS; + + memcpy(CMSG_DATA(cmsg), &sock_fd, sizeof(sock_fd)); + -+ msg.msg_control = cmsg; ++ msg.msg_control = cmsg; + msg.msg_controllen = cmsg->cmsg_len; + -+ if (processor->status == CHILD_STATUS_STANDBY) -+ { ++ if (processor->status == CHILD_STATUS_STANDBY) { + _DBG("Activating child #%d", processor->id); + processor->status = CHILD_STATUS_STARTING; + } + -+ _DBG("Writing message to %d, passing sock_fd: %d", processor->senv->output, sock_fd); ++ _DBG("Writing message to %d, passing sock_fd: %d", processor->senv->output, ++ sock_fd); + _DBG("header_len=%d headers=\"%s\"", header_len, h.headers); + _DBG("body_len=%d body=\"%s\"", body_len, body); + -+ if ((rv = sendmsg(processor->senv->output, &msg, 0)) == -1) -+ { ++ if ((rv = sendmsg(processor->senv->output, &msg, 0)) == -1) { + apr_pool_destroy(pool); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Writing message failed %d %d", rv, errno); @@ -1602,7 +1594,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +} + +static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id, -+ apr_bucket_alloc_t *bucket_alloc, apr_pool_t *pool) ++ apr_bucket_alloc_t *bucket_alloc, apr_pool_t *pool) +{ + conn_rec *current_conn; + int sock_fd; @@ -1619,41 +1611,49 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, + sbh, bucket_alloc); + _DBG("Looking up the right vhost"); ++ + if (current_conn) { + ap_update_vhost_given_ip(current_conn); -+ _DBG("Base server is %s, name based vhosts %s", current_conn->base_server->server_hostname, ++ _DBG("Base server is %s, name based vhosts %s", ++ current_conn->base_server->server_hostname, + current_conn->vhost_lookup_data ? "on" : "off"); -+ -+ // check for ssl configuration for this server (ssl_server_is_https is NULL if we have no mod_ssl) -+ if(ssl_server_is_https) ssl_on = ssl_server_is_https(current_conn->base_server); ++ ++ /* check for ssl configuration for this server ++ * (ssl_server_is_https is NULL if we have no mod_ssl) */ ++ if (ssl_server_is_https) { ++ ssl_on = ssl_server_is_https(current_conn->base_server); ++ } + } + -+ if (current_conn && (!current_conn->vhost_lookup_data || ssl_on) && CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) { -+ _DBG("We are not using name based vhosts (or SSL is enabled), we'll directly pass the socket."); ++ if (current_conn && (!current_conn->vhost_lookup_data || ssl_on) ++ && CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) { ++ _DBG("We are not using name based vhosts (or SSL is enabled), " ++ "we'll directly pass the socket."); + + sconf = PERUSER_SERVER_CONF(current_conn->base_server->module_config); + + if (sconf->senv != NULL) { + processor = &CHILD_INFO_TABLE[sconf->senv->processor_id]; + -+ _DBG("Forwarding without further inspection, processor %d", processor->id); -+ if (processor->status == CHILD_STATUS_STANDBY) -+ { -+ _DBG("Activating child #%d", processor->id); -+ processor->status = CHILD_STATUS_STARTING; -+ } -+ ++ _DBG("Forwarding without further inspection, processor %d", ++ processor->id); ++ ++ if (processor->status == CHILD_STATUS_STANDBY) { ++ _DBG("Activating child #%d", processor->id); ++ processor->status = CHILD_STATUS_STARTING; ++ } ++ + _DBG("Creating new pool",0); + apr_pool_create(&ptrans, pool); + + _DBG("Passing request.",0); + if (pass_socket(sock, processor, ptrans) == -1) { + if (processor->senv->error_pass == 0) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, -+ ap_server_conf, "Could not pass request to proper " -+ "child, request will not be honoured."); ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, ++ "Could not pass request to proper child, " ++ "request will not be honoured."); + } -+ ++ + processor->senv->error_pass = 1; + } + else { @@ -1664,60 +1664,58 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + _DBG("Base server has no senv set!"); + + if (sconf->missing_senv_reported == 0) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, -+ ap_server_conf, "Virtualhost %s has no server environment set, " -+ "request will not be honoured.", current_conn->base_server->server_hostname); ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, ++ "Virtualhost %s has no server environment set, " ++ "request will not be honoured.", ++ current_conn->base_server->server_hostname); + } + + sconf->missing_senv_reported = 1; + } + -+ if (current_conn) -+ { -+ _DBG("freeing connection",0); ++ if (current_conn) { ++ _DBG("freeing connection", 0); + ap_lingering_close(current_conn); + } + -+ _DBG("doing longjmp",0); ++ _DBG("doing longjmp", 0); + longjmp(CHILD_INFO_TABLE[my_child_num].jmpbuffer, 1); -+ return; ++ return; + } + -+ if ((rv = apr_os_sock_get(&sock_fd, sock)) != APR_SUCCESS) -+ { ++ if ((rv = apr_os_sock_get(&sock_fd, sock)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get"); + } + + _DBG("child_num=%d sock=%ld sock_fd=%d", my_child_num, sock, sock_fd); -+ _DBG("type=%s %d", child_type_string(CHILD_INFO_TABLE[my_child_num].type), my_child_num); ++ _DBG("type=%s %d", child_type_string(CHILD_INFO_TABLE[my_child_num].type), ++ my_child_num); + +#ifdef _OSD_POSIX + if (sock_fd >= FD_SETSIZE) + { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, -+ "new file descriptor %d is too large; you probably need " -+ "to rebuild Apache with a larger FD_SETSIZE " -+ "(currently %d)", -+ sock_fd, FD_SETSIZE); ++ "new file descriptor %d is too large; you probably need " ++ "to rebuild Apache with a larger FD_SETSIZE " ++ "(currently %d)", ++ sock_fd, FD_SETSIZE); + apr_socket_close(sock); + _DBG("child_num=%d: exiting with error", my_child_num); + return; + } +#endif + -+ if (CHILD_INFO_TABLE[my_child_num].sock_fd < 0) -+ { ++ if (CHILD_INFO_TABLE[my_child_num].sock_fd < 0) { + ap_sock_disable_nagle(sock); + } + + if (!current_conn) { + ap_create_sb_handle(&sbh, p, conn_id, 0); -+ current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, -+ sbh, bucket_alloc); ++ current_conn = ap_run_create_connection(p, ap_server_conf, sock, ++ conn_id, sbh, bucket_alloc); + } + -+ if (current_conn) -+ { ++ if (current_conn) { + ap_process_connection(current_conn, sock); + ap_lingering_close(current_conn); + } @@ -1729,31 +1727,37 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + apr_bucket_brigade *bb; + core_net_rec *net; + -+ _DBG("function entered",0); ++ _DBG("function entered", 0); + + /* -- fetch our sockets from the pool -- */ -+ apr_pool_userdata_get((void **)&bb, "PERUSER_SOCKETS", conn->pool); -+ if (bb != NULL) -+ { -+ /* -- find the 'core' filter and give the socket data to it -- */ -+ for (filter = conn->output_filters; filter != NULL; filter = filter->next) -+ { -+ if (!strcmp(filter->frec->name, "core")) break; -+ } -+ if (filter != NULL) -+ { -+ net = filter->ctx; -+ net->in_ctx = apr_palloc(conn->pool, sizeof(*net->in_ctx)); -+ net->in_ctx->b = bb; -+ net->in_ctx->tmpbb = apr_brigade_create(net->in_ctx->b->p, -+ net->in_ctx->b->bucket_alloc); ++ apr_pool_userdata_get((void **) &bb, "PERUSER_SOCKETS", conn->pool); ++ ++ if (bb == NULL) { ++ return DECLINED; ++ } ++ ++ /* -- find the 'core' filter and give the socket data to it -- */ ++ for (filter = conn->output_filters; filter != NULL; ++ filter = filter->next) { ++ if (!strcmp(filter->frec->name, "core")) { ++ break; + } + } -+ _DBG("leaving (DECLINED)", 0); ++ ++ if (filter == NULL) { ++ return DECLINED; ++ } ++ ++ net = filter->ctx; ++ net->in_ctx = apr_palloc(conn->pool, sizeof(*net->in_ctx)); ++ net->in_ctx->b = bb; ++ net->in_ctx->tmpbb = apr_brigade_create(net->in_ctx->b->p, ++ net->in_ctx->b->bucket_alloc); ++ + return DECLINED; +} + -+static int pass_request(request_rec *r, child_info_t *processor) ++static int pass_request(request_rec *r, child_info_t *child) +{ + int rv; + struct msghdr msg; @@ -1774,60 +1778,75 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + const apr_table_entry_t *headers_in; + int counter; + -+ apr_socket_t *thesock = ap_get_module_config(r->connection->conn_config, &core_module); ++ apr_socket_t *thesock = ap_get_module_config(r->connection->conn_config, ++ &core_module); + -+ if ((!r->the_request) || (!strlen(r->the_request))) -+ { ++ if (!r->the_request || !strlen(r->the_request)) { + _DBG("empty request. dropping it (%ld)", r->the_request); + return -1; + } + -+ if (!processor) -+ { ++ if (!child) { + _DBG("server %s in child %d has no child_info associated", -+ r->hostname, my_child_num); ++ r->hostname, my_child_num); + return -1; + } + + _DBG("passing request to another child. Vhost: %s, child %d %d", -+ apr_table_get(r->headers_in, "Host"), my_child_num, processor->senv->output); -+ _DBG("r->the_request=\"%s\" len=%d", r->the_request, strlen(r->the_request)); ++ apr_table_get(r->headers_in, "Host"), my_child_num, ++ child->senv->output); ++ ++ _DBG("r->the_request=\"%s\" len=%d", r->the_request, ++ strlen(r->the_request)); + + /* Make sure there are free workers on the other end */ -+ if (wait_for_workers(processor) == -1) return -1; ++ if (child->type != CHILD_TYPE_MULTIPLEXER && wait_for_workers(child) == -1) { ++ return -1; ++ } ++ ++ ap_get_brigade(r->connection->input_filters, bb, AP_MODE_EXHAUSTIVE, ++ APR_NONBLOCK_READ, len); + -+ ap_get_brigade(r->connection->input_filters, bb, AP_MODE_EXHAUSTIVE, APR_NONBLOCK_READ, len); -+ + /* Scan the brigade looking for heap-buckets */ -+ + _DBG("Scanning the brigade",0); + bucket = APR_BRIGADE_FIRST(bb); -+ while (bucket != APR_BRIGADE_SENTINEL(bb) && -+ APR_BUCKET_IS_HEAP(bucket)) { -+ _DBG("HEAP BUCKET is found, length=%d", bucket->length); ++ ++ while (bucket != APR_BRIGADE_SENTINEL(bb) && APR_BUCKET_IS_HEAP(bucket)) { ++ _DBG("HEAP BUCKET is found, length=%d", bucket->length); ++ + bucket = APR_BUCKET_NEXT(bucket); ++ + if (!APR_BUCKET_IS_HEAP(bucket)) { -+ _DBG("NON-HEAP BUCKET is found, extracting the part of brigade before it",0); ++ _DBG("NON-HEAP BUCKET is found, extracting the part of brigade " ++ "before it"); ++ + body_bb = bb; + bb = apr_brigade_split(body_bb, bucket); ++ + /* Do we need to apr_destroy_brigade(bb) here? + * Yeah, I know we do apr_pool_destroy(r->pool) before return, but + * ap_get_brigade is in non-blocking mode (however len is zero). + */ -+ if (apr_brigade_pflatten(body_bb, &body, &body_len, r->pool) != APR_SUCCESS) { ++ if (apr_brigade_pflatten(body_bb, &body, &body_len, r->pool) ++ != APR_SUCCESS) { ++ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, -+ "Unable to flatten brigade, declining request"); ++ "Unable to flatten brigade, declining request"); ++ + apr_pool_destroy(r->pool); + return DECLINED; + } ++ + _DBG("Brigade is flattened as body (body_len=%d)", body_len); + } + } -+ _DBG("Scanning is finished",0); ++ ++ _DBG("Scanning is finished"); + + apr_os_sock_get(&sock_fd, thesock); ++ + /* looks like a bug while sending/receiving SCM_RIGHTS related to ipv6 -+ workaround: send remote_addr structure too */ ++ workaround: send remote_addr structure too */ + apr_socket_addr_get(&remote_addr, APR_REMOTE, thesock); + + h.p = r->pool; @@ -1836,58 +1855,59 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + headers_in = (const apr_table_entry_t *) headers_in_array->elts; + + h.headers = apr_pstrcat(h.p, r->the_request, CRLF, NULL); ++ + for (counter = 0; counter < headers_in_array->nelts; counter++) { -+ if (headers_in[counter].key == NULL -+ || headers_in[counter].val == NULL) { -+ continue; -+ } -+ h.headers = apr_pstrcat(h.p, h.headers, headers_in[counter].key, ": ", -+ headers_in[counter].val, CRLF, NULL); ++ if (headers_in[counter].key == NULL || ++ headers_in[counter].val == NULL) { ++ continue; ++ } + ++ h.headers = apr_pstrcat(h.p, h.headers, headers_in[counter].key, ": ", ++ headers_in[counter].val, CRLF, NULL); + } ++ + h.headers = apr_pstrcat(h.p, h.headers, CRLF, NULL); + ap_xlate_proto_to_ascii(h.headers, strlen(h.headers)); + + header_len = strlen(h.headers); + + iov[0].iov_base = &header_len; -+ iov[0].iov_len = sizeof(header_len); ++ iov[0].iov_len = sizeof(header_len); + iov[1].iov_base = &body_len; -+ iov[1].iov_len = sizeof(body_len); ++ iov[1].iov_len = sizeof(body_len); + iov[2].iov_base = remote_addr; -+ iov[2].iov_len = sizeof(*remote_addr); ++ iov[2].iov_len = sizeof(*remote_addr); + iov[3].iov_base = h.headers; -+ iov[3].iov_len = strlen(h.headers) + 1; ++ iov[3].iov_len = strlen(h.headers) + 1; + iov[4].iov_base = body; -+ iov[4].iov_len = body_len; ++ iov[4].iov_len = body_len; + -+ msg.msg_name = NULL; ++ msg.msg_name = NULL; + msg.msg_namelen = 0; -+ msg.msg_iov = iov; -+ msg.msg_iovlen = 5; ++ msg.msg_iov = iov; ++ msg.msg_iovlen = 5; + + cmsg = apr_palloc(r->pool, sizeof(*cmsg) + sizeof(sock_fd)); -+ cmsg->cmsg_len = CMSG_LEN(sizeof(sock_fd)); ++ cmsg->cmsg_len = CMSG_LEN(sizeof(sock_fd)); + cmsg->cmsg_level = SOL_SOCKET; -+ cmsg->cmsg_type = SCM_RIGHTS; ++ cmsg->cmsg_type = SCM_RIGHTS; + + memcpy(CMSG_DATA(cmsg), &sock_fd, sizeof(sock_fd)); + -+ msg.msg_control = cmsg; ++ msg.msg_control = cmsg; + msg.msg_controllen = cmsg->cmsg_len; + -+ if (processor->status == CHILD_STATUS_STANDBY) -+ { -+ _DBG("Activating child #%d", processor->id); -+ processor->status = CHILD_STATUS_STARTING; ++ if (child->status == CHILD_STATUS_STANDBY) { ++ _DBG("Activating child #%d", child->id); ++ child->status = CHILD_STATUS_STARTING; + } + -+ _DBG("Writing message to %d, passing sock_fd: %d", processor->senv->output, sock_fd); ++ _DBG("Writing message to %d, passing sock_fd: %d", child->senv->output, ++ sock_fd); + _DBG("header_len=%d headers=\"%s\"", header_len, h.headers); + _DBG("body_len=%d body=\"%s\"", body_len, body); + -+ if ((rv = sendmsg(processor->senv->output, &msg, 0)) == -1) -+ { ++ if ((rv = sendmsg(child->senv->output, &msg, 0)) == -1) { + apr_pool_destroy(r->pool); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, + "Writing message failed %d %d", rv, errno); @@ -1904,12 +1924,9 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return 1; +} + -+ -+static apr_status_t receive_from_multiplexer( -+ void **trans_sock, /* will be filled out w/ the received socket */ -+ ap_listen_rec *lr, /* listener to receive from */ -+ apr_pool_t *ptrans /* transaction wide pool */ -+) ++static apr_status_t receive_connection(void **trans_sock, ++ ap_listen_rec *lr, ++ apr_pool_t *ptrans) +{ + struct msghdr msg; + struct cmsghdr *cmsg; @@ -1926,27 +1943,27 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + /* -- bucket's, brigades and their allocators */ + apr_bucket_alloc_t *alloc = apr_bucket_alloc_create(ptrans); -+ apr_bucket_brigade *bb = apr_brigade_create(ptrans, alloc); -+ apr_bucket *bucket; ++ apr_bucket_brigade *bb = apr_brigade_create(ptrans, alloc); ++ apr_bucket *bucket; + + /* prepare the buffers for receiving data from remote side */ + iov[0].iov_base = &header_len; -+ iov[0].iov_len = sizeof(header_len); ++ iov[0].iov_len = sizeof(header_len); + iov[1].iov_base = &body_len; -+ iov[1].iov_len = sizeof(body_len); ++ iov[1].iov_len = sizeof(body_len); + iov[2].iov_base = &remote_addr; -+ iov[2].iov_len = sizeof(remote_addr); -+ iov[3].iov_base = (char*)&buff; -+ iov[3].iov_len = HUGE_STRING_LEN; ++ iov[2].iov_len = sizeof(remote_addr); ++ iov[3].iov_base = (char*) &buff; ++ iov[3].iov_len = HUGE_STRING_LEN; + + cmsg = apr_palloc(ptrans, sizeof(*cmsg) + sizeof(trans_sock_fd)); + cmsg->cmsg_len = CMSG_LEN(sizeof(trans_sock_fd)); + -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ msg.msg_iov = iov; -+ msg.msg_iovlen = 4; -+ msg.msg_control = cmsg; ++ msg.msg_name = NULL; ++ msg.msg_namelen = 0; ++ msg.msg_iov = iov; ++ msg.msg_iovlen = 4; ++ msg.msg_control = cmsg; + msg.msg_controllen = cmsg->cmsg_len; + + /* -- receive data from socket -- */ @@ -1958,69 +1975,73 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (ret == -1 && errno == EAGAIN) { + _DBG("receive_from_multiplexer recvmsg() EAGAIN, someone was faster"); -+ ++ + return APR_EAGAIN; + } + else if (ret == -1) { + _DBG("recvmsg failed with error \"%s\"", strerror(errno)); -+ ++ + // Error, better kill this child to be on the safe side + return APR_EGENERAL; + } -+ else _DBG("recvmsg returned %d", ret); ++ else ++ _DBG("recvmsg returned %d", ret); + + /* -- extract socket from the cmsg -- */ + memcpy(&trans_sock_fd, CMSG_DATA(cmsg), sizeof(trans_sock_fd)); ++ + /* here *trans_sock always == NULL (socket reset at got_fd), so -+ we can use apr_os_sock_make() instead of apr_os_sock_put() */ -+ sockinfo.os_sock = &trans_sock_fd; -+ sockinfo.local = NULL; -+ sockinfo.remote = (struct sockaddr *)&remote_addr.sa.sin; -+ sockinfo.family = remote_addr.family; -+ sockinfo.type = SOCK_STREAM; ++ we can use apr_os_sock_make() instead of apr_os_sock_put() */ ++ ++ sockinfo.os_sock = &trans_sock_fd; ++ sockinfo.local = NULL; ++ sockinfo.remote = (struct sockaddr *) &remote_addr.sa.sin; ++ sockinfo.family = remote_addr.family; ++ sockinfo.type = SOCK_STREAM; +#ifdef APR_ENABLE_FOR_1_0 + sockinfo.protocol = 0; +#endif -+ apr_os_sock_make((apr_socket_t **)trans_sock, &sockinfo, ptrans); ++ apr_os_sock_make((apr_socket_t **) trans_sock, &sockinfo, ptrans); + apr_os_sock_get(&fd_tmp, *trans_sock); + + _DBG("trans_sock=%ld fdx=%d sock_fd=%d", -+ *trans_sock, trans_sock_fd, fd_tmp); ++ *trans_sock, trans_sock_fd, fd_tmp); + + apr_cpystrn(headers, buff, header_len + 1); + _DBG("header_len=%d headers=\"%s\"", header_len, headers); + -+ if (header_len) { ++ if (header_len) { + _DBG("header_len > 0, we got a request", 0); + /* -- store received data into an brigade and add -+ it to the current transaction's pool -- */ ++ it to the current transaction's pool -- */ + bucket = apr_bucket_eos_create(alloc); + APR_BRIGADE_INSERT_HEAD(bb, bucket); + bucket = apr_bucket_socket_create(*trans_sock, alloc); + APR_BRIGADE_INSERT_HEAD(bb, bucket); -+ ++ + if (body_len) { -+ body = (char*)&buff[header_len + 1]; ++ body = (char*) &buff[header_len + 1]; + _DBG("body_len=%d body=\"%s\"", body_len, body); -+ ++ + bucket = apr_bucket_heap_create(body, body_len, NULL, alloc); + APR_BRIGADE_INSERT_HEAD(bb, bucket); -+ } else { ++ } ++ else { + _DBG("There is no body",0); + } -+ ++ + bucket = apr_bucket_heap_create(headers, header_len, NULL, alloc); -+ ++ + APR_BRIGADE_INSERT_HEAD(bb, bucket); + apr_pool_userdata_set(bb, "PERUSER_SOCKETS", NULL, ptrans); -+ } else { ++ } ++ else { + _DBG("header_len == 0, we got a socket only", 0); + } -+ _DBG("returning 0", 0); ++ + return 0; +} + -+ +/* Set group privileges. + * + * Note that we use the username as set in the config files, rather than @@ -2030,8 +2051,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +static int set_group_privs(uid_t uid, gid_t gid) +{ -+ if (!geteuid()) -+ { ++ if (!geteuid()) { + struct passwd *ent; + const char *name; + @@ -2039,27 +2059,24 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + * Set the GID before initgroups(), since on some platforms + * setgid() is known to zap the group list. + */ -+ if (setgid(gid) == -1) -+ { ++ if (setgid(gid) == -1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "setgid: unable to set group id to Group %u", -+ (unsigned)gid); ++ (unsigned) gid); + return -1; + } + + /* if getpwuid() fails, just skip initgroups() */ + -+ if ((ent = getpwuid(uid)) != NULL) -+ { ++ if ((ent = getpwuid(uid)) != NULL) { + name = ent->pw_name; + + /* Reset `groups' attributes. */ + -+ if (initgroups(name, gid) == -1) -+ { ++ if (initgroups(name, gid) == -1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "initgroups: unable to set groups for User %s " -+ "and Group %u", name, (unsigned)gid); ++ "and Group %u", name, (unsigned) gid); + return -1; + } + } @@ -2067,7 +2084,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return 0; +} + -+static int peruser_setup_cgroup(int childnum, server_env_t *senv, apr_pool_t *pool) ++static int peruser_setup_cgroup(int childnum, server_env_t *senv, ++ apr_pool_t *pool) +{ + apr_file_t *file; + int length; @@ -2079,22 +2097,23 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + length = strlen(senv->cgroup) + CGROUP_TASKS_FILE_LEN; + tasks_file = malloc(length); + -+ if (!tasks_file) return -1; ++ if (!tasks_file) { ++ return -1; ++ } + + pos = apr_cpystrn(tasks_file, senv->cgroup, length); + apr_cpystrn(pos, CGROUP_TASKS_FILE, CGROUP_TASKS_FILE_LEN); + + /* Prepare the data to be written to tasks file */ + content = apr_itoa(pool, ap_my_pid); -+ content_len = strlen(content); ++ content_len = strlen(content); + + _DBG("writing pid %s to tasks file %s", content, tasks_file); + + if (apr_file_open(&file, tasks_file, APR_WRITE, APR_OS_DEFAULT, pool)) { + if (senv->error_cgroup == 0) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, -+ "cgroup: unable to open file %s", -+ tasks_file); ++ "cgroup: unable to open file %s", tasks_file); + } + + senv->error_cgroup = 1; @@ -2105,9 +2124,9 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + if (apr_file_write(file, content, &content_len)) { + if (senv->error_cgroup == 0) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, -+ "cgroup: unable to write pid to file %s", -+ tasks_file); ++ "cgroup: unable to write pid to file %s", tasks_file); + } ++ + senv->error_cgroup = 1; + } + else { @@ -2131,17 +2150,17 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + nice(senv->nice_lvl); + } + -+ if(senv->chroot) { ++ if (senv->chroot) { + _DBG("chdir to %s", senv->chroot); + -+ if(chdir(senv->chroot)) { ++ if (chdir(senv->chroot)) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "chdir: unable to change to directory: %s", + senv->chroot); + return -1; + } + -+ if(chroot(senv->chroot)) { ++ if (chroot(senv->chroot)) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "chroot: unable to chroot to directory: %s", + senv->chroot); @@ -2149,41 +2168,44 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + } + -+ if(senv->cgroup) { -+ peruser_setup_cgroup(childnum, senv, pool); ++ if (senv->cgroup) { ++ peruser_setup_cgroup(childnum, senv, pool); + } + + if (senv->uid == -1 && senv->gid == -1) { + return unixd_setup_child(); + } ++ + if (set_group_privs(senv->uid, senv->gid)) { + return -1; + } ++ + /* Only try to switch if we're running as root */ -+ if (!geteuid() -+ && ( ++ if (!geteuid() && ( +#ifdef _OSD_POSIX + os_init_job_environment(ap_server_conf, unixd_config.user_name, -+ one_process) != 0 || ++ one_process) != 0 || +#endif + setuid(senv->uid) == -1)) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, -+ "setuid: unable to change to uid: %ld", -+ (long) senv->uid); ++ "setuid: unable to change to uid: %ld", (long) senv->uid); + return -1; + } ++ + return 0; +} + +static int check_signal(int signum) +{ + _DBG("signum=%d", signum); ++ + switch (signum) { + case SIGTERM: + case SIGINT: + just_die(signum); + return 1; + } ++ + return 0; +} + @@ -2192,38 +2214,45 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + * In other words, don't change this one without checking table_do in alloc.c. + * It returns true unless there was a write error of some kind. + */ -+static int peruser_header_field(peruser_header *h, -+ const char *fieldname, const char *fieldval) ++static int peruser_header_field(peruser_header *h, const char *fieldname, ++ const char *fieldval) +{ + apr_pstrcat(h->p, h->headers, fieldname, ": ", fieldval, CRLF, NULL); ++ + return 1; +} + -+static inline ap_listen_rec* listen_add(apr_pool_t* pool, apr_socket_t *sock, void* accept_func) ++static inline ap_listen_rec* listen_add(apr_pool_t* pool, apr_socket_t *sock, ++ void* accept_func) +{ + ap_listen_rec *lr_walk, *lr_new; + + _DBG("function entered", 0); ++ + /* -- create an new listener for this child -- */ + lr_new = apr_palloc(pool, sizeof(*lr_new)); -+ lr_new->sd = sock; -+ lr_new->active = 1; ++ lr_new->sd = sock; ++ lr_new->active = 1; + lr_new->accept_func = accept_func; -+ lr_new->next = NULL; ++ lr_new->next = NULL; + + /* -- add the new listener_rec into the list -- */ + /* FIXME: should we somehow lock this list ? */ + lr_walk = ap_listeners; -+ if (lr_walk) -+ { -+ while (lr_walk->next) lr_walk = lr_walk->next; ++ ++ if (lr_walk) { ++ while (lr_walk->next) { ++ lr_walk = lr_walk->next; ++ } ++ + lr_walk->next = lr_new; + } -+ else -+ { ++ else { + ap_listeners = lr_walk = lr_new; + } ++ + num_listensocks++; ++ + return lr_new; +} + @@ -2234,13 +2263,13 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + _DBG("function entered", 0); + + /* FIXME: should we somehow lock this list ? */ -+ while (ap_listeners) -+ { ++ while (ap_listeners) { + lr_walk = ap_listeners->next; + apr_socket_close(ap_listeners->sd); + ap_listeners = lr_walk; + } -+ num_listensocks=0; ++ ++ num_listensocks = 0; +} + +apr_status_t cleanup_child_info(void *d) @@ -2287,17 +2316,18 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + apr_socket_t *sock = NULL; + apr_socket_t *pod_sock = NULL; + -+ mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this -+ * child initializes -+ */ ++ /* for benefit of any hooks that run as this ++ * child initializes ++ */ ++ mpm_state = AP_MPMQ_STARTING; + + my_child_num = child_num_arg; + ap_my_pid = getpid(); + requests_this_child = 0; + + _DBG("sock_fd_in=%d sock_fd_out=%d", -+ CHILD_INFO_TABLE[my_child_num].senv->input, -+ CHILD_INFO_TABLE[my_child_num].senv->output); ++ CHILD_INFO_TABLE[my_child_num].senv->input, ++ CHILD_INFO_TABLE[my_child_num].senv->output); + + /* Get a sub context for global allocations in this child, so that + * we can have cleanups occur when the child exits. @@ -2320,35 +2350,44 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + clean_child_exit(APEXIT_CHILDFATAL); + } + -+ switch(CHILD_INFO_TABLE[my_child_num].type) -+ { -+ case CHILD_TYPE_MULTIPLEXER: -+ _DBG("MULTIPLEXER %d", my_child_num); -+ break; ++ switch (CHILD_INFO_TABLE[my_child_num].type) { ++ case CHILD_TYPE_MULTIPLEXER: ++ _DBG("MULTIPLEXER %d", my_child_num); + -+ case CHILD_TYPE_PROCESSOR: -+ case CHILD_TYPE_WORKER: -+ _DBG("%s %d", child_type_string(CHILD_INFO_TABLE[my_child_num].type), my_child_num); ++ /* -- create new listener to receive from workers -- */ ++ apr_os_sock_put(&sock, &CHILD_INFO_TABLE[my_child_num].senv->input, ++ pconf); ++ listen_add(pconf, sock, receive_connection); ++ break; + -+ /* -- create new listener to receive from multiplexer -- */ -+ apr_os_sock_put(&sock, &CHILD_INFO_TABLE[my_child_num].senv->input, pconf); -+ listen_clear(); -+ listen_add(pconf, sock, receive_from_multiplexer); ++ case CHILD_TYPE_PROCESSOR: ++ case CHILD_TYPE_WORKER: ++ _DBG("%s %d", child_type_string(CHILD_INFO_TABLE[my_child_num].type), ++ my_child_num); + -+ break; ++ /* -- create new listener to receive from multiplexer -- */ ++ apr_os_sock_put(&sock, &CHILD_INFO_TABLE[my_child_num].senv->input, ++ pconf); ++ listen_clear(); ++ listen_add(pconf, sock, receive_connection); ++ ++ break; + -+ default: -+ _DBG("unspecified child type for %d sleeping a while ...", my_child_num); -+ sleep(5); -+ return; ++ default: ++ _DBG("unspecified child type for %d sleeping a while ...", ++ my_child_num); ++ ++ sleep(5); ++ return; + } + + apr_os_file_get(&fd, pipe_of_death_in); + apr_os_sock_put(&pod_sock, &fd, pconf); + listen_add(pconf, pod_sock, check_pipe_of_death); + -+ if(peruser_setup_child(my_child_num, pchild) != 0) ++ if (peruser_setup_child(my_child_num, pchild) != 0) { + clean_child_exit(APEXIT_CHILDFATAL); ++ } + + ap_run_child_init(pchild, ap_server_conf); + @@ -2356,8 +2395,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); + + /* Set up the pollfd array */ -+ listensocks = apr_pcalloc(pchild, -+ sizeof(*listensocks) * (num_listensocks)); ++ listensocks = apr_pcalloc(pchild, sizeof(*listensocks) * (num_listensocks)); ++ + for (lr = ap_listeners, i = 0; i < num_listensocks; lr = lr->next, i++) { + listensocks[i].accept_func = lr->accept_func; + listensocks[i].sd = lr->sd; @@ -2376,29 +2415,30 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + bucket_alloc = apr_bucket_alloc_create(pchild); + + while (!die_now) { -+ /* -+ * (Re)initialize this child to a pre-connection state. -+ */ ++ /* ++ * (Re)initialize this child to a pre-connection state. ++ */ + -+ current_conn = NULL; ++ current_conn = NULL; + -+ apr_pool_clear(ptrans); ++ apr_pool_clear(ptrans); + -+ if (CHILD_INFO_TABLE[my_child_num].type != CHILD_TYPE_MULTIPLEXER -+ && ap_max_requests_per_child > 0 -+ && requests_this_child++ >= ap_max_requests_per_child) { ++ if (CHILD_INFO_TABLE[my_child_num].type != CHILD_TYPE_MULTIPLEXER ++ && ap_max_requests_per_child > 0 ++ && requests_this_child++ >= ap_max_requests_per_child) { + _DBG("max requests reached, dying now", 0); -+ clean_child_exit(0); -+ } ++ clean_child_exit(0); ++ } + + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); + + CHILD_INFO_TABLE[my_child_num].status = CHILD_STATUS_READY; -+ _DBG("Child %d (%s) is now ready", my_child_num, child_type_string(CHILD_INFO_TABLE[my_child_num].type)); ++ _DBG("Child %d (%s) is now ready", my_child_num, ++ child_type_string(CHILD_INFO_TABLE[my_child_num].type)); + -+ /* -+ * Wait for an acceptable connection to arrive. -+ */ ++ /* ++ * Wait for an acceptable connection to arrive. ++ */ + + /* Lock around "accept", if necessary */ + if (CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) { @@ -2410,54 +2450,63 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + else { + /* multiple listening sockets - need to poll */ -+ for (;;) { ++ for (;;) { + apr_status_t ret; + apr_int32_t n; + + ret = apr_poll(pollset, num_listensocks, &n, -1); ++ + if (ret != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(ret)) { + continue; + } -+ /* Single Unix documents select as returning errnos -+ * EBADF, EINTR, and EINVAL... and in none of those -+ * cases does it make sense to continue. In fact -+ * on Linux 2.0.x we seem to end up with EFAULT -+ * occasionally, and we'd loop forever due to it. -+ */ -+ ap_log_error(APLOG_MARK, APLOG_ERR, ret, ap_server_conf, -+ "apr_poll: (listen)"); -+ clean_child_exit(1); ++ ++ /* Single Unix documents select as returning errnos ++ * EBADF, EINTR, and EINVAL... and in none of those ++ * cases does it make sense to continue. In fact ++ * on Linux 2.0.x we seem to end up with EFAULT ++ * occasionally, and we'd loop forever due to it. ++ */ ++ ap_log_error(APLOG_MARK, APLOG_ERR, ret, ap_server_conf, ++ "apr_poll: (listen)"); ++ clean_child_exit(1); + } ++ + /* find a listener */ + curr_pollfd = last_pollfd; + do { + curr_pollfd++; ++ + if (curr_pollfd >= num_listensocks) { + curr_pollfd = 0; + } ++ + /* XXX: Should we check for POLLERR? */ + if (pollset[curr_pollfd].rtnevents & APR_POLLIN) { + last_pollfd = curr_pollfd; + offset = curr_pollfd; + goto got_fd; + } -+ } while (curr_pollfd != last_pollfd); ++ } ++ while (curr_pollfd != last_pollfd); + + continue; + } + } -+ got_fd: ++ ++ got_fd: ++ + _DBG("input available ... resetting socket.",0); -+ sock = NULL; /* important! */ ++ sock = NULL; /* important! */ + + /* if we accept() something we don't want to die, so we have to + * defer the exit + */ -+ status = listensocks[offset].accept_func((void *)&sock, &listensocks[offset], ptrans); ++ status = listensocks[offset].accept_func((void *) &sock, ++ &listensocks[offset], ptrans); + + if (CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) { -+ SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */ ++ SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */ + } + + if (status == APR_EGENERAL) { @@ -2470,45 +2519,48 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (CHILD_INFO_TABLE[my_child_num].status == CHILD_STATUS_READY) { + CHILD_INFO_TABLE[my_child_num].status = CHILD_STATUS_ACTIVE; -+ _DBG("Child %d (%s) is now active", my_child_num, child_type_string(CHILD_INFO_TABLE[my_child_num].type)); ++ _DBG("Child %d (%s) is now active", my_child_num, ++ child_type_string(CHILD_INFO_TABLE[my_child_num].type)); + } + -+ if (CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_PROCESSOR || -+ CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_WORKER || -+ CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) -+ { -+ _DBG("CHECKING IF WE SHOULD CLONE A CHILD..."); -+ -+ _DBG("total_processors = %d, max_processors = %d", -+ total_processors(my_child_num), -+ CHILD_INFO_TABLE[my_child_num].senv->max_processors); -+ -+ _DBG("idle_processors = %d, min_free_processors = %d", -+ idle_processors(my_child_num), -+ CHILD_INFO_TABLE[my_child_num].senv->min_free_processors); -+ -+ if(total_processors(my_child_num) < -+ CHILD_INFO_TABLE[my_child_num].senv->max_processors && -+ (idle_processors(my_child_num) <= -+ CHILD_INFO_TABLE[my_child_num].senv->min_free_processors || -+ total_processors(my_child_num) < -+ CHILD_INFO_TABLE[my_child_num].senv->min_processors -+ )) -+ { -+ _DBG("CLONING CHILD"); -+ child_clone(); -+ } ++ if (CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_PROCESSOR ++ || CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_WORKER ++ || CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) { ++ ++ _DBG("CHECKING IF WE SHOULD CLONE A CHILD..."); ++ ++ _DBG("total_processors = %d, max_processors = %d", ++ total_processors(my_child_num), ++ CHILD_INFO_TABLE[my_child_num].senv->max_processors); ++ ++ _DBG("idle_processors = %d, min_free_processors = %d", ++ idle_processors(my_child_num), ++ CHILD_INFO_TABLE[my_child_num].senv->min_free_processors); ++ ++ if (total_processors(my_child_num) ++ < CHILD_INFO_TABLE[my_child_num].senv->max_processors ++ && (idle_processors(my_child_num) ++ <= CHILD_INFO_TABLE[my_child_num].senv->min_free_processors ++ || total_processors(my_child_num) ++ < CHILD_INFO_TABLE[my_child_num].senv->min_processors)) { ++ ++ _DBG("CLONING CHILD"); ++ child_clone(); ++ } + } + -+ if (!setjmp(CHILD_INFO_TABLE[my_child_num].jmpbuffer)) -+ { ++ if (!setjmp(CHILD_INFO_TABLE[my_child_num].jmpbuffer)) { + _DBG("marked jmpbuffer",0); ++ ++ CHILD_INFO_TABLE[my_child_num].senv->stats_connections++; ++ + _TRACE_CALL("process_socket()",0); ++ + process_socket(ptrans, sock, my_child_num, bucket_alloc, pchild); ++ + _TRACE_RET("process_socket()",0); + } -+ else -+ { ++ else { + _DBG("landed from longjmp",0); + CHILD_INFO_TABLE[my_child_num].sock_fd = AP_PERUSER_THISCHILD; + } @@ -2522,17 +2574,17 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + _DBG("ap_mpm_pod_check(pod) = APR_SUCCESS; dying now", 0); + die_now = 1; + } -+ else if (ap_my_generation != -+ ap_scoreboard_image->global->running_generation) { /* restart? */ ++ else if (ap_my_generation ++ != ap_scoreboard_image->global->running_generation) { + /* yeah, this could be non-graceful restart, in which case the + * parent will kill us soon enough, but why bother checking? + */ -+ _DBG("ap_my_generation != ap_scoreboard_image->global->running_generation; dying now", 0); ++ _DBG("ap_my_generation !=" ++ " ap_scoreboard_image->global->running_generation; dying now"); + die_now = 1; + } + -+ if(CHILD_INFO_TABLE[my_child_num].status == CHILD_STATUS_RESTART) -+ { ++ if (CHILD_INFO_TABLE[my_child_num].status == CHILD_STATUS_RESTART) { + _DBG("restarting", 0); + die_now = 1; + } @@ -2542,40 +2594,43 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + clean_child_exit(0); +} + -+static server_env_t* find_senv_by_name(const char *name) { ++static server_env_t* find_senv_by_name(const char *name) ++{ + int i; + -+ if (name == NULL) return NULL; ++ if (name == NULL) { ++ return NULL; ++ } + + _DBG("name=%s", name); + -+ for(i = 0; i < NUM_SENV; i++) -+ { -+ if(SENV[i].name != NULL && !strcmp(SENV[i].name, name)) { -+ return &SENV[i]; -+ } -+ } ++ for (i = 0; i < NUM_SENV; i++) { ++ if (SENV[i].name != NULL && !strcmp(SENV[i].name, name)) { ++ return &SENV[i]; ++ } ++ } + + return NULL; +} + -+static server_env_t* find_matching_senv(server_env_t* senv) { ++static server_env_t* find_matching_senv(server_env_t* senv) ++{ + int i; + -+ _DBG("name=%s uid=%d gid=%d chroot=%s", senv->name, senv->uid, senv->gid, senv->chroot); -+ -+ for(i = 0; i < NUM_SENV; i++) -+ { -+ if((senv->name != NULL && SENV[i].name != NULL && !strcmp(SENV[i].name, senv->name)) || -+ (senv->name == NULL && SENV[i].uid == senv->uid && SENV[i].gid == senv->gid && -+ ( -+ (SENV[i].chroot == NULL && senv->chroot == NULL) || -+ ((SENV[i].chroot != NULL || senv->chroot != NULL) && !strcmp(SENV[i].chroot, senv->chroot))) -+ ) -+ ) { -+ return &SENV[i]; -+ } -+ } ++ _DBG("name=%s uid=%d gid=%d chroot=%s", senv->name, senv->uid, senv->gid, ++ senv->chroot); ++ ++ for (i = 0; i < NUM_SENV; i++) { ++ if ((senv->name != NULL && SENV[i].name != NULL ++ && !strcmp(SENV[i].name, senv->name)) ++ || (senv->name == NULL && SENV[i].uid == senv->uid ++ && SENV[i].gid == senv->gid ++ && ((SENV[i].chroot == NULL && senv->chroot == NULL) ++ || ((SENV[i].chroot != NULL || senv->chroot != NULL) ++ && !strcmp(SENV[i].chroot, senv->chroot))))) { ++ return &SENV[i]; ++ } ++ } + + return NULL; +} @@ -2591,15 +2646,16 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (old_senv) { + _DBG("Found existing senv"); ++ + senv = old_senv; ++ + return old_senv; + } + -+ if(NUM_SENV >= server_limit) -+ { -+ _DBG("server_limit reached!"); -+ return NULL; -+ } ++ if (NUM_SENV >= server_limit) { ++ _DBG("server_limit reached!"); ++ return NULL; ++ } + + _DBG("Creating new senv"); + @@ -2608,32 +2664,31 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + SENV[NUM_SENV].availability = 100; + + socketpair(PF_UNIX, SOCK_STREAM, 0, socks); -+ SENV[NUM_SENV].input = socks[0]; ++ SENV[NUM_SENV].input = socks[0]; + SENV[NUM_SENV].output = socks[1]; + + senv = &SENV[NUM_SENV]; + return &SENV[server_env_image->control->num++]; +} + -+ +static const char* child_clone() +{ + int i; + child_info_t *this; + child_info_t *new; + -+ for(i = 0; i < NUM_CHILDS; i++) -+ { -+ if(CHILD_INFO_TABLE[i].pid == 0 && -+ CHILD_INFO_TABLE[i].type == CHILD_TYPE_UNKNOWN) break; ++ for (i = 0; i < NUM_CHILDS; i++) { ++ if (CHILD_INFO_TABLE[i].pid == 0 ++ && CHILD_INFO_TABLE[i].type == CHILD_TYPE_UNKNOWN) { ++ break; ++ } + } -+ -+ if(i == NUM_CHILDS && NUM_CHILDS >= server_limit) -+ { ++ ++ if (i == NUM_CHILDS && NUM_CHILDS >= server_limit) { + _DBG("Trying to use more child ID's than ServerLimit. " -+ "Increase ServerLimit in your config file."); ++ "Increase ServerLimit in your config file."); + return NULL; -+ } ++ } + + _DBG("cloning child #%d from #%d", i, my_child_num); + @@ -2652,49 +2707,67 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + new->sock_fd = this->sock_fd; + new->status = CHILD_STATUS_STARTING; + -+ if(i == NUM_CHILDS) child_info_image->control->num++; ++ if (i == NUM_CHILDS) { ++ child_info_image->control->num++; ++ } ++ + return NULL; +} + -+static const char* child_add(int type, int status, -+ apr_pool_t *pool, server_env_t *senv) ++static const char* child_add(int type, int status, apr_pool_t *pool, ++ server_env_t *senv) +{ -+ _DBG("adding child #%d", NUM_CHILDS); ++ int i; + -+ if(NUM_CHILDS >= server_limit) -+ { ++ for (i = 0; i < NUM_CHILDS; i++) { ++ if (CHILD_INFO_TABLE[i].pid == 0 ++ && CHILD_INFO_TABLE[i].type == CHILD_TYPE_UNKNOWN) { ++ break; ++ } ++ } ++ ++ _DBG("adding child #%d", i); ++ ++ if (i >= server_limit) { + return "Trying to use more child ID's than ServerLimit. " -+ "Increase ServerLimit in your config file."; ++ "Increase ServerLimit in your config file."; + } + -+ if (senv->chroot && !ap_is_directory(pool, senv->chroot)) -+ return apr_psprintf(pool, "Error: chroot directory [%s] does not exist", senv->chroot); ++ if (senv->chroot && !ap_is_directory(pool, senv->chroot)) { ++ return apr_psprintf(pool, ++ "Error: chroot directory [%s] does not exist", ++ senv->chroot); ++ } + -+ CHILD_INFO_TABLE[NUM_CHILDS].senv = senv_add(senv); ++ CHILD_INFO_TABLE[i].senv = senv_add(senv); + -+ if(CHILD_INFO_TABLE[NUM_CHILDS].senv == NULL) -+ { ++ if (CHILD_INFO_TABLE[i].senv == NULL) { + return "Trying to use more server environments than ServerLimit. " -+ "Increase ServerLimit in your config file."; ++ "Increase ServerLimit in your config file."; + } + -+ if(type != CHILD_TYPE_WORKER) -+ CHILD_INFO_TABLE[NUM_CHILDS].senv->processor_id = NUM_CHILDS; ++ if (type == CHILD_TYPE_MULTIPLEXER) { ++ multiplexer_senv = CHILD_INFO_TABLE[i].senv; ++ } + -+ CHILD_INFO_TABLE[NUM_CHILDS].type = type; -+ CHILD_INFO_TABLE[NUM_CHILDS].sock_fd = AP_PERUSER_THISCHILD; -+ CHILD_INFO_TABLE[NUM_CHILDS].status = status; ++ if (type != CHILD_TYPE_WORKER) { ++ CHILD_INFO_TABLE[i].senv->processor_id = i; ++ } + -+ _DBG("[%d] uid=%d gid=%d type=%d chroot=%s", -+ NUM_CHILDS, senv->uid, senv->gid, type, -+ senv->chroot); ++ CHILD_INFO_TABLE[i].type = type; ++ CHILD_INFO_TABLE[i].sock_fd = AP_PERUSER_THISCHILD; ++ CHILD_INFO_TABLE[i].status = status; + -+ if (senv->uid == 0 || senv->gid == 0) -+ { ++ _DBG("[%d] uid=%d gid=%d type=%d chroot=%s", i, senv->uid, ++ senv->gid, type, senv->chroot); ++ ++ if (senv->uid == 0 || senv->gid == 0) { + _DBG("Assigning root user/group to a child.", 0); + } + -+ child_info_image->control->num++; ++ if (i >= NUM_CHILDS) { ++ child_info_image->control->num = i + 1; ++ } + + return NULL; +} @@ -2706,31 +2779,29 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + _DBG("function entered", 0); + dump_server_env_image(); + -+ switch (CHILD_INFO_TABLE[slot].type) -+ { -+ case CHILD_TYPE_MULTIPLEXER: break; -+ case CHILD_TYPE_PROCESSOR: break; -+ case CHILD_TYPE_WORKER: break; ++ switch (CHILD_INFO_TABLE[slot].type) { ++ case CHILD_TYPE_MULTIPLEXER: ++ break; ++ case CHILD_TYPE_PROCESSOR: ++ break; ++ case CHILD_TYPE_WORKER: ++ break; + -+ default: -+ _DBG("no valid client in slot %d", slot); -+ /* sleep(1); */ -+ return 0; -+ } -+ -+ if (slot + 1 > ap_max_daemons_limit) { -+ ap_max_daemons_limit = slot + 1; ++ default: ++ _DBG("no valid client in slot %d", slot); ++ /* sleep(1); */ ++ return 0; + } + + if (one_process) { -+ apr_signal(SIGHUP, just_die); ++ apr_signal(SIGHUP, just_die); + /* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */ -+ apr_signal(SIGINT, just_die); ++ apr_signal(SIGINT, just_die); +#ifdef SIGQUIT -+ apr_signal(SIGQUIT, SIG_DFL); ++ apr_signal(SIGQUIT, SIG_DFL); +#endif -+ apr_signal(SIGTERM, just_die); -+ child_main(slot); ++ apr_signal(SIGTERM, just_die); ++ child_main(slot); + } + + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, @@ -2738,29 +2809,29 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + CHILD_INFO_TABLE[slot].status = CHILD_STATUS_READY; + -+ +#ifdef _OSD_POSIX + /* BS2000 requires a "special" version of fork() before a setuid() call */ + if ((pid = os_fork(unixd_config.user_name)) == -1) { +#elif defined(TPF) -+ if ((pid = os_fork(s, slot)) == -1) { ++ if ((pid = os_fork(s, slot)) == -1) { +#else + if ((pid = fork()) == -1) { +#endif -+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process"); ++ ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, ++ "fork: Unable to fork new process"); + -+ /* fork didn't succeed. Fix the scoreboard or else -+ * it will say SERVER_STARTING forever and ever -+ */ -+ (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, ++ /* fork didn't succeed. Fix the scoreboard or else ++ * it will say SERVER_STARTING forever and ever ++ */ ++ (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, + (request_rec *) NULL); + -+ /* In case system resources are maxxed out, we don't want -+ Apache running away with the CPU trying to fork over and -+ over and over again. */ -+ sleep(10); ++ /* In case system resources are maxxed out, we don't want ++ Apache running away with the CPU trying to fork over and ++ over and over again. */ ++ sleep(10); + -+ return -1; ++ return -1; + } + + if (!pid) { @@ -2768,38 +2839,33 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + /* by default AIX binds to a single processor + * this bit unbinds children which will then bind to another cpu + */ -+ int status = bindprocessor(BINDPROCESS, (int)getpid(), -+ PROCESSOR_CLASS_ANY); -+ if (status != OK) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, -+ ap_server_conf, "processor unbind failed %d", status); -+ } ++ int status = bindprocessor(BINDPROCESS, (int)getpid(), ++ PROCESSOR_CLASS_ANY); ++ if (status != OK) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ++ ap_server_conf, "processor unbind failed %d", status); ++ } +#endif -+ RAISE_SIGSTOP(MAKE_CHILD); -+ AP_MONCONTROL(1); ++ RAISE_SIGSTOP(MAKE_CHILD); AP_MONCONTROL(1); + /* Disable the parent's signal handlers and set up proper handling in + * the child. -+ */ -+ apr_signal(SIGHUP, just_die); -+ apr_signal(SIGTERM, just_die); ++ */ ++ apr_signal(SIGHUP, just_die); ++ apr_signal(SIGTERM, just_die); + /* The child process doesn't do anything for AP_SIG_GRACEFUL. + * Instead, the pod is used for signalling graceful restart. + */ + /* apr_signal(AP_SIG_GRACEFUL, restart); */ -+ child_main(slot); ++ child_main(slot); + clean_child_exit(0); + } + + ap_scoreboard_image->parent[slot].pid = pid; -+ CHILD_INFO_TABLE[slot].pid = pid; -+ -+ ap_child_table[slot].pid = pid; -+ ap_child_table[slot].status = SERVER_ALIVE; ++ CHILD_INFO_TABLE[slot].pid = pid; + + return 0; +} + -+ +/* + * idle_spawn_rate is the number of children that will be spawned on the + * next maintenance cycle if there aren't enough idle servers. It is @@ -2813,119 +2879,109 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +static int total_processes(int child_num) +{ + int i, total; -+ for(i = 0, total = 0; i < NUM_CHILDS; ++i) -+ { -+ if(CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv && -+ (!(CHILD_INFO_TABLE[i].type == CHILD_TYPE_PROCESSOR && -+ CHILD_INFO_TABLE[i].status == CHILD_STATUS_STANDBY))) -+ { -+ total++; ++ ++ for (i = 0, total = 0; i < NUM_CHILDS; ++i) { ++ if (CHILD_INFO_TABLE[i].senv == CHILD_INFO_TABLE[child_num].senv ++ && CHILD_INFO_TABLE[i].status != CHILD_STATUS_STANDBY) { ++ total++; + } + } ++ + return total; +} + ++static int determine_child_fate(int childnum, child_info_t *child, ++ worker_score *child_sb, apr_time_t now) ++{ ++ time_t idle_time = apr_time_sec(now - child_sb->last_used); ++ ++ if (total_processes(childnum) <= child->senv->min_processors) { ++ /* We will not kill a child, if the senv needs live workers */ ++ return 0; ++ } ++ ++ if (child->type == CHILD_TYPE_PROCESSOR || ++ child->type == CHILD_TYPE_WORKER) { ++ ++ if (idle_processors(childnum) <= child->senv->min_free_processors || ++ child->senv->min_free_processors == 0) { ++ /* We will not kill a child, if the senv needs idle workers */ ++ return 0; ++ } ++ ++ if (expire_timeout > 0 && idle_time > expire_timeout) { ++ /* Child has not handled a request for some time now, stop it */ ++ _DBG("Expire timeout reached for child #%d", childnum); ++ return 1; ++ } ++ ++ if (idle_timeout > 0 && child_sb->status == SERVER_READY ++ && idle_time > idle_timeout) { ++ /* Child has been idle for too long, stop it */ ++ _DBG("Idle timeout reached for child #%d", childnum); ++ return 1; ++ } ++ ++ if (child->senv->max_free_processors > 0 ++ && idle_processors(childnum) >= child->senv->max_free_processors) { ++ /* Too many spare workers available */ ++ _DBG("Too many spare workers for processor %s, stopping child #%d", ++ child->senv->name, childnum); ++ return 1; ++ } ++ } else if (child->type == CHILD_TYPE_MULTIPLEXER) { ++ if (multiplexer_idle_timeout > 0 && child_sb->status == SERVER_READY ++ && idle_time > multiplexer_idle_timeout) { ++ /* Multiplexer has been idle for too long, stop it */ ++ _DBG("Stopping idle multiplexer #%d", childnum); ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ +static void perform_idle_server_maintenance(apr_pool_t *p) +{ -+ int i; ++ int i, stop_child; ++ time_t idle_time; ++ child_info_t *child; ++ worker_score *child_sb; + apr_time_t now; + -+ /* _DBG("function entered", 0); */ -+ + now = apr_time_now(); + -+ for (i = 0; i < NUM_CHILDS; ++i) -+ { -+ if(CHILD_INFO_TABLE[i].pid == 0) -+ { -+ if(CHILD_INFO_TABLE[i].status == CHILD_STATUS_STARTING) -+ make_child(ap_server_conf, i); -+ } -+ else if( -+ (((CHILD_INFO_TABLE[i].type == CHILD_TYPE_PROCESSOR || -+ CHILD_INFO_TABLE[i].type == CHILD_TYPE_WORKER) && -+ ap_scoreboard_image->parent[i].pid > 1) && -+ (idle_processors (i) > CHILD_INFO_TABLE[i].senv->min_free_processors || CHILD_INFO_TABLE[i].senv->min_free_processors == 0) && -+ total_processes (i) > CHILD_INFO_TABLE[i].senv->min_processors && -+ ( -+ (expire_timeout > 0 && ap_scoreboard_image->servers[i][0].status != SERVER_DEAD && -+ apr_time_sec(now - ap_scoreboard_image->servers[i][0].last_used) > expire_timeout) || -+ (idle_timeout > 0 && ap_scoreboard_image->servers[i][0].status == SERVER_READY && -+ apr_time_sec(now - ap_scoreboard_image->servers[i][0].last_used) > idle_timeout) || -+ (CHILD_INFO_TABLE[i].senv->max_free_processors > 0 && CHILD_INFO_TABLE[i].status == CHILD_STATUS_READY && -+ idle_processors(i) > CHILD_INFO_TABLE[i].senv->max_free_processors)) -+ ) -+ || (CHILD_INFO_TABLE[i].type == CHILD_TYPE_MULTIPLEXER && -+ (multiplexer_idle_timeout > 0 && ap_scoreboard_image->servers[i][0].status == SERVER_READY && -+ apr_time_sec(now - ap_scoreboard_image->servers[i][0].last_used) > multiplexer_idle_timeout) && -+ total_processors(i) > CHILD_INFO_TABLE[i].senv->min_processors -+ ) -+ ) -+ { -+ CHILD_INFO_TABLE[i].pid = 0; -+ CHILD_INFO_TABLE[i].status = CHILD_STATUS_STANDBY; -+ -+ if(CHILD_INFO_TABLE[i].type == CHILD_TYPE_WORKER || CHILD_INFO_TABLE[i].type == CHILD_TYPE_MULTIPLEXER) -+ { -+ /* completely free up this slot */ ++ for (i = 0; i < NUM_CHILDS; ++i) { ++ child = &CHILD_INFO_TABLE[i]; ++ child_sb = &ap_scoreboard_image->servers[i][0]; + -+ CHILD_INFO_TABLE[i].senv = (server_env_t*)NULL; -+ CHILD_INFO_TABLE[i].type = CHILD_TYPE_UNKNOWN; -+ CHILD_INFO_TABLE[i].sock_fd = -3; /* -1 and -2 are taken */ ++ if (child->status == CHILD_STATUS_STANDBY) { ++ continue; + } -+ if(kill(ap_scoreboard_image->parent[i].pid, SIGTERM) == -1) -+ { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, -+ ap_server_conf, "kill SIGTERM"); ++ ++ if (child->pid == 0) { ++ if (child->status == CHILD_STATUS_STARTING) { ++ make_child(ap_server_conf, i); ++ } ++ ++ continue; + } -+ -+ -+ ap_update_child_status_from_indexes(i, 0, SERVER_DEAD, NULL); -+ } -+ } -+ -+ for(i=0;i<grace_children;i++) { -+ if (child_grace_info_table[i].pid > 0 && expire_timeout > 0 && -+ apr_time_sec(now - child_grace_info_table[i].last_used) > expire_timeout) { -+ -+ _DBG("Killing a child from last graceful (pid=%d,childno=%d,last_used=%d)", -+ child_grace_info_table[i].pid, child_grace_info_table[i].id, -+ child_grace_info_table[i].last_used); -+ -+ if(kill(child_grace_info_table[i].pid, SIGTERM) == -1) -+ { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, -+ ap_server_conf, "kill SIGTERM"); ++ ++ if (ap_scoreboard_image->parent[i].pid == 0) { ++ continue; ++ } ++ ++ if (determine_child_fate(i, child, child_sb, now) == 1) { ++ child->status = CHILD_STATUS_STANDBY; ++ ++ if (kill(ap_scoreboard_image->parent[i].pid, SIGTERM) == -1) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "kill SIGTERM"); + } -+ -+ /* We don't need to do remove_grace_child() here, -+ * because it will be automatically done once -+ * the child dies by ap_mpm_run() */ -+ } ++ } + } +} + -+int remove_grace_child(int slot) { -+ if (slot < grace_children) { -+ child_grace_info_table[slot].id = 0; -+ child_grace_info_table[slot].pid = 0; -+ child_grace_info_table[slot].status = CHILD_STATUS_STANDBY; -+ child_grace_info_table[slot].type = CHILD_TYPE_UNKNOWN; -+ child_grace_info_table[slot].last_used = 0; -+ grace_children_alive--; -+ -+ if (grace_children_alive <= 0) { /* All children have returned from graceful */ -+ _DBG("Every child has returned from graceful restart - freeing child_grace_info_table"); -+ grace_children_alive = 0; -+ is_graceful = 0; -+ grace_children = 0; -+ free(child_grace_info_table); -+ } -+ return 0; -+ } -+ return 1; -+} -+ +/***************************************************************** + * Executive routines. + */ @@ -2933,10 +2989,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int i; -+/* int fd; */ ++ /* int fd; */ + apr_status_t rv; + apr_size_t one = 1; -+/* apr_socket_t *sock = NULL; */ ++ unsigned char status; ++ /* apr_socket_t *sock = NULL; */ + + ap_log_pid(pconf, ap_pid_fname); + @@ -2955,7 +3012,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + ap_server_root_relative(_pconf, ap_lock_fname), + ap_my_pid); + -+ rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, ++ rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, + ap_accept_lock_mech, _pconf); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, @@ -2965,8 +3022,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + +#if APR_USE_SYSVSEM_SERIALIZE -+ if (ap_accept_lock_mech == APR_LOCK_DEFAULT || -+ ap_accept_lock_mech == APR_LOCK_SYSVSEM) { ++ if (ap_accept_lock_mech == APR_LOCK_DEFAULT || ++ ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif @@ -2974,7 +3031,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on cross-process lock; " -+ "check User and Group directives"); ++ "check User and Group directives"); + mpm_state = AP_MPMQ_STOPPING; + return 1; + } @@ -2991,15 +3048,6 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + ap_scoreboard_image->global->running_generation = ap_my_generation; + } + -+ /* Initialize the child table */ -+ if (!is_graceful) -+ { -+ for (i = 0; i < server_limit; i++) -+ { -+ ap_child_table[i].pid = 0; -+ } -+ } -+ + /* We need to put the new listeners at the end of the ap_listeners + * list. If we don't, then the pool will be cleared before the + * open_logs phase is called for the second time, and ap_listeners @@ -3008,12 +3056,12 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + * won't start. + */ + -+/* -+ apr_os_file_get(&fd, pipe_of_death_in); -+ apr_os_sock_put(&sock, &fd, pconf); ++ /* ++ apr_os_file_get(&fd, pipe_of_death_in); ++ apr_os_sock_put(&sock, &fd, pconf); + -+ listen_add(pconf, sock, check_pipe_of_death); -+*/ ++ listen_add(pconf, sock, check_pipe_of_death); ++ */ + set_signals(); + + if (one_process) { @@ -3021,15 +3069,15 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, -+ "%s configured -- resuming normal operations", -+ ap_get_server_version()); -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, -+ "Server built: %s", ap_get_server_built()); ++ "%s configured -- resuming normal operations", ++ ap_get_server_version()); ++ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, "Server built: %s", ++ ap_get_server_built()); +#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, -+ "AcceptMutex: %s (default: %s)", -+ apr_proc_mutex_name(accept_mutex), -+ apr_proc_mutex_defname()); ++ "AcceptMutex: %s (default: %s)", ++ apr_proc_mutex_name(accept_mutex), ++ apr_proc_mutex_defname()); +#endif + restart_pending = shutdown_pending = 0; + @@ -3038,105 +3086,113 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + _DBG("sizeof(child_info_t) = %d", sizeof(child_info_t)); + + while (!restart_pending && !shutdown_pending) { -+ int child_slot; ++ int child_slot = -1; + apr_exit_why_e exitwhy; -+ int status, processed_status; ++ int status, processed_status; + /* this is a memory leak, but I'll fix it later. */ -+ apr_proc_t pid; ++ apr_proc_t pid; + + ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + -+ /* XXX: if it takes longer than 1 second for all our children -+ * to start up and get into IDLE state then we may spawn an -+ * extra child -+ */ -+ if (pid.pid != -1) { ++ /* XXX: if it takes longer than 1 second for all our children ++ * to start up and get into IDLE state then we may spawn an ++ * extra child ++ */ ++ if (pid.pid != -1) { + processed_status = ap_process_child_status(&pid, exitwhy, status); + if (processed_status == APEXIT_CHILDFATAL) { + mpm_state = AP_MPMQ_STOPPING; + return 1; + } -+ -+ if (grace_children > 0) { -+ for(i=0;i<grace_children;i++) { -+ if (child_grace_info_table[i].pid == pid.pid) { -+ break; -+ } -+ } -+ if (i != grace_children) { -+ _DBG("Child returned from graceful (%d)", i); -+ remove_grace_child(i); -+ continue; -+ } -+ } + + /* non-fatal death... note that it's gone in the scoreboard. */ -+ child_slot = find_child_by_pid(&pid); -+ _DBG("child #%d has died ...", child_slot); -+ -+ for (i = 0; i < ap_max_daemons_limit; ++i) -+ { -+ if (ap_child_table[i].pid == pid.pid) -+ { ++ for (i = 0; i < NUM_CHILDS; ++i) { ++ if (CHILD_INFO_TABLE[i].pid == pid.pid) { + child_slot = i; + break; + } + } + -+ if (child_slot >= 0) { -+ ap_child_table[child_slot].pid = 0; ++ _DBG("child #%d (pid=%d) has died", child_slot, pid.pid); ++ ++ if (child_slot >= 0) { ++ CHILD_INFO_TABLE[child_slot].pid = 0; ++ ++ status = ap_scoreboard_image->servers[child_slot][0].status; ++ + _TRACE_CALL("ap_update_child_status_from_indexes", 0); -+ (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD, -+ (request_rec *) NULL); ++ ++ (void)ap_update_child_status_from_indexes(child_slot, 0, ++ SERVER_DEAD, ++ (request_rec *)NULL); ++ + _TRACE_RET("ap_update_child_status_from_indexes", 0); + + if (processed_status == APEXIT_CHILDSICK) { -+ /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc) ++ /* child detected a resource shortage (E[NM]FILE, ENOBUFS, ++ * etc) + * cut the fork rate to the minimum + */ + _DBG("processed_status = APEXIT_CHILDSICK", 0); -+ idle_spawn_rate = 1; ++ idle_spawn_rate = 1; ++ } ++ else if (status == SERVER_GRACEFUL) { ++ _DBG("cleaning child from last generation"); ++ memset(&CHILD_INFO_TABLE[child_slot], 0, sizeof(child_info_t)); ++ CHILD_INFO_TABLE[child_slot].id = child_slot; + } -+ else if (CHILD_INFO_TABLE[child_slot].status == CHILD_STATUS_STANDBY) { ++ else if (CHILD_INFO_TABLE[child_slot].status ++ == CHILD_STATUS_STANDBY) ++ { + _DBG("leaving child in standby state", 0); ++ ++ if (CHILD_INFO_TABLE[child_slot].type == CHILD_TYPE_WORKER ++ || CHILD_INFO_TABLE[child_slot].type == CHILD_TYPE_MULTIPLEXER) { ++ /* completely free up this slot */ ++ CHILD_INFO_TABLE[child_slot].senv = (server_env_t*) NULL; ++ CHILD_INFO_TABLE[child_slot].type = CHILD_TYPE_UNKNOWN; ++ CHILD_INFO_TABLE[child_slot].sock_fd = -3; /* -1 and -2 are taken */ ++ } + } -+ else if (child_slot < ap_daemons_limit && -+ CHILD_INFO_TABLE[child_slot].type != -+ CHILD_TYPE_UNKNOWN) { -+ /* we're still doing a 1-for-1 replacement of dead -+ * children with new children -+ */ ++ else if (child_slot < ap_daemons_limit ++ && CHILD_INFO_TABLE[child_slot].type ++ != CHILD_TYPE_UNKNOWN) ++ { ++ /* we're still doing a 1-for-1 replacement of dead ++ * children with new children ++ */ + _DBG("replacing by new child ...", 0); -+ make_child(ap_server_conf, child_slot); -+ } ++ make_child(ap_server_conf, child_slot); ++ } +#if APR_HAS_OTHER_CHILD -+ } -+ else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, status) == APR_SUCCESS) { ++ } ++ else if (apr_proc_other_child_alert(&pid, APR_OC_REASON_DEATH, ++ status) == APR_SUCCESS) { + _DBG("Already handled", 0); -+ /* handled */ ++ /* handled */ +#endif -+ } -+ else if (is_graceful) { -+ /* Great, we've probably just lost a slot in the -+ * scoreboard. Somehow we don't know about this -+ * child. -+ */ ++ } ++ else if (is_graceful) { ++ /* Great, we've probably just lost a slot in the ++ * scoreboard. Somehow we don't know about this ++ * child. ++ */ + _DBG("long lost child came home, whatever that means", 0); + -+ ap_log_error(APLOG_MARK, APLOG_WARNING, -+ 0, ap_server_conf, -+ "long lost child came home! (pid %ld)", (long)pid.pid); -+ } -+ /* Don't perform idle maintenance when a child dies, -+ * only do it when there's a timeout. Remember only a -+ * finite number of children can die, and it's pretty -+ * pathological for a lot to die suddenly. -+ */ -+ continue; -+ } -+ -+ perform_idle_server_maintenance(pconf); -+ ++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, ++ "long lost child came home! (pid %ld)", ++ (long) pid.pid); ++ } ++ /* Don't perform idle maintenance when a child dies, ++ * only do it when there's a timeout. Remember only a ++ * finite number of children can die, and it's pretty ++ * pathological for a lot to die suddenly. ++ */ ++ continue; ++ } ++ ++ perform_idle_server_maintenance(pconf); ++ +#ifdef TPF + shutdown_pending = os_check_server(tpf_server_name); + ap_check_signals(); @@ -3147,35 +3203,35 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + mpm_state = AP_MPMQ_STOPPING; + + if (shutdown_pending) { -+ /* Time to gracefully shut down: -+ * Kill child processes, tell them to call child_exit, etc... -+ */ -+ if (unixd_killpg(getpgrp(), SIGTERM) < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM"); -+ } -+ ap_reclaim_child_processes(1); /* Start with SIGTERM */ -+ -+ /* cleanup pid file on normal shutdown */ -+ { -+ const char *pidfile = NULL; -+ pidfile = ap_server_root_relative (pconf, ap_pid_fname); -+ if ( pidfile != NULL && unlink(pidfile) == 0) -+ ap_log_error(APLOG_MARK, APLOG_INFO, -+ 0, ap_server_conf, -+ "removed PID file %s (pid=%ld)", -+ pidfile, (long)getpid()); -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, -+ "caught SIGTERM, shutting down"); -+ return 1; ++ /* Time to gracefully shut down: ++ * Kill child processes, tell them to call child_exit, etc... ++ */ ++ if (unixd_killpg(getpgrp(), SIGTERM) < 0) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "killpg SIGTERM"); ++ } ++ ap_reclaim_child_processes(1); /* Start with SIGTERM */ ++ ++ /* cleanup pid file on normal shutdown */ ++ { ++ const char *pidfile = NULL; ++ pidfile = ap_server_root_relative(pconf, ap_pid_fname); ++ if (pidfile != NULL && unlink(pidfile) == 0) ++ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, ++ "removed PID file %s (pid=%ld)", pidfile, ++ (long) getpid()); ++ } ++ ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, ++ "caught SIGTERM, shutting down"); ++ return 1; + } + + /* we've been told to restart */ + apr_signal(SIGHUP, SIG_IGN); + if (one_process) { -+ /* not worth thinking about */ -+ return 1; ++ /* not worth thinking about */ ++ return 1; + } + + /* advance to the next generation */ @@ -3184,7 +3240,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + */ + ++ap_my_generation; + ap_scoreboard_image->global->running_generation = ap_my_generation; -+ ++ + /* cleanup sockets */ + for (i = 0; i < NUM_SENV; i++) { + close(SENV[i].input); @@ -3194,100 +3250,45 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + if (is_graceful) { + char char_of_death = AP_PERUSER_CHAR_OF_DEATH; + -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, -+ "Graceful restart requested, doing restart"); -+ -+#if 0 -+ /* kill off the idle ones */ -+ ap_mpm_pod_killpg(pod, ap_max_daemons_limit); -+ -+ /* This is mostly for debugging... so that we know what is still -+ * gracefully dealing with existing request. This will break -+ * in a very nasty way if we ever have the scoreboard totally -+ * file-based (no shared memory) -+ */ -+ for (i = 0; i < ap_daemons_limit; ++i) { -+ if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { -+ ap_scoreboard_image->servers[i][0].status = SERVER_GRACEFUL; -+ } -+ } -+#endif -+ -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, -+ ap_server_conf, AP_SIG_GRACEFUL_STRING " received. " -+ "Doing graceful restart"); ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, ++ "Graceful restart requested, doing restart"); + + /* This is mostly for debugging... so that we know what is still -+ * gracefully dealing with existing request. ++ * gracefully dealing with existing request. This will break ++ * in a very nasty way if we ever have the scoreboard totally ++ * file-based (no shared memory) + */ -+ -+ int alivechildren = 0; -+ child_grace_info_t* old_grace_info; -+ -+ for (i = 0; i < NUM_CHILDS; ++i) -+ { -+ ((ap_child_table[i].pid) && (ap_child_table[i].status = SERVER_DYING)); -+ -+ if (CHILD_INFO_TABLE[i].pid) { -+ alivechildren++; ++ for (i = 0; i < ap_daemons_limit; ++i) { ++ if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { ++ ap_scoreboard_image->servers[i][0].status = SERVER_GRACEFUL; + } + } -+ -+ _DBG("Initializing child_grace_info_table", 0); -+ -+ if (alivechildren > 0) { -+ if (grace_children > 0) { -+ old_grace_info = child_grace_info_table; -+ _DBG("%d children still living from last graceful " -+ "- adding to new child_grace_info_table", -+ grace_children); -+ } -+ -+ child_grace_info_table = (child_grace_info_t*)calloc(alivechildren+grace_children, -+ sizeof(child_grace_info_t)); -+ -+ if (grace_children > 0) { -+ for(i=0;i<grace_children;i++) { -+ child_grace_info_table[i] = old_grace_info[i]; -+ } -+ grace_children = i; -+ free(old_grace_info); -+ } -+ else grace_children = 0; -+ -+ } ++ ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, ++ AP_SIG_GRACEFUL_STRING " received. " ++ "Doing graceful restart"); + + /* give the children the signal to die */ -+ for (i = 0; i < NUM_CHILDS;) -+ { -+ if ((rv = apr_file_write(pipe_of_death_out, &char_of_death, &one)) != APR_SUCCESS) -+ { -+ if (APR_STATUS_IS_EINTR(rv)) continue; ++ for (i = 0; i < NUM_CHILDS;i++) { ++ if ((rv = apr_file_write(pipe_of_death_out, &char_of_death, &one)) ++ != APR_SUCCESS) { ++ if (APR_STATUS_IS_EINTR(rv)) { ++ continue; ++ } + ap_log_error(APLOG_MARK, APLOG_WARNING, rv, ap_server_conf, + "write pipe_of_death"); + } -+ if (CHILD_INFO_TABLE[i].pid) { -+ child_grace_info_table[grace_children].id = CHILD_INFO_TABLE[i].id; -+ child_grace_info_table[grace_children].pid = CHILD_INFO_TABLE[i].pid; -+ child_grace_info_table[grace_children].status = CHILD_INFO_TABLE[i].status; -+ child_grace_info_table[grace_children].type = CHILD_INFO_TABLE[i].type; -+ child_grace_info_table[grace_children].last_used= ap_scoreboard_image->servers[i][0].last_used; -+ grace_children++; -+ grace_children_alive++; -+ } -+ i++; + } -+ _DBG("Total children of %d leaving behind for graceful restart (%d living)", -+ grace_children, grace_children_alive); + } + else { -+ /* Kill 'em off */ -+ if (unixd_killpg(getpgrp(), SIGHUP) < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP"); -+ } -+ ap_reclaim_child_processes(0); /* Not when just starting up */ -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, -+ "SIGHUP received. Attempting to restart"); ++ /* Kill 'em off */ ++ if (unixd_killpg(getpgrp(), SIGHUP) < 0) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, ++ "killpg SIGHUP"); ++ } ++ ap_reclaim_child_processes(0); /* Not when just starting up */ ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, ++ "SIGHUP received. Attempting to restart"); + } + + return 0; @@ -3296,8 +3297,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +/* == allocate an private server config structure == */ +static void *peruser_create_config(apr_pool_t *p, server_rec *s) +{ -+ peruser_server_conf *c = (peruser_server_conf *) -+ apr_pcalloc(p, sizeof(peruser_server_conf)); ++ peruser_server_conf *c = ++ (peruser_server_conf *) apr_pcalloc(p, sizeof(peruser_server_conf)); + + c->senv = NULL; + c->missing_senv_reported = 0; @@ -3308,7 +3309,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +/* This really should be a post_config hook, but the error log is already + * redirected by that point, so we need to do this in the open_logs phase. + */ -+static int peruser_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) ++static int peruser_open_logs(apr_pool_t *p, apr_pool_t *plog, ++ apr_pool_t *ptemp, server_rec *s) +{ + apr_status_t rv; + @@ -3316,26 +3318,28 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { -+ ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, -+ NULL, "no listening sockets available, shutting down"); -+ return DONE; ++ ap_log_error(APLOG_MARK, APLOG_ALERT | APLOG_STARTUP, 0, NULL, ++ "no listening sockets available, shutting down"); ++ return DONE; + } + + ap_log_pid(pconf, ap_pid_fname); + + if ((rv = ap_mpm_pod_open(pconf, &pod))) { -+ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, -+ "Could not open pipe-of-death."); ++ ap_log_error(APLOG_MARK, APLOG_CRIT | APLOG_STARTUP, rv, NULL, ++ "Could not open pipe-of-death."); + return DONE; + } + -+ if ((rv = apr_file_pipe_create(&pipe_of_death_in, &pipe_of_death_out, -+ pconf)) != APR_SUCCESS) { ++ if ((rv = apr_file_pipe_create(&pipe_of_death_in, ++ &pipe_of_death_out, pconf)) ++ != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, + (const server_rec*) ap_server_conf, + "apr_file_pipe_create (pipe_of_death)"); + exit(1); + } ++ + if ((rv = apr_file_pipe_timeout_set(pipe_of_death_in, 0)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, + (const server_rec*) ap_server_conf, @@ -3347,7 +3351,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +} + +static int restart_num = 0; -+static int peruser_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) ++static int peruser_pre_config(apr_pool_t *p, apr_pool_t *plog, ++ apr_pool_t *ptemp) +{ + int no_detach, debug, foreground, i; + int tmp_server_limit = DEFAULT_SERVER_LIMIT; @@ -3364,8 +3369,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + foreground = one_process = 1; + no_detach = 0; + } -+ else -+ { ++ else { + no_detach = ap_exists_config_define("NO_DETACH"); + one_process = ap_exists_config_define("ONE_PROCESS"); + foreground = ap_exists_config_define("FOREGROUND"); @@ -3375,7 +3379,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + if (restart_num++ == 1) { + if (!one_process && !foreground) { + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND -+ : APR_PROC_DETACH_DAEMONIZE); ++ : APR_PROC_DETACH_DAEMONIZE); ++ + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); @@ -3400,7 +3405,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 1; +#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE -+ ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; ++ ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; +#endif + + expire_timeout = DEFAULT_EXPIRE_TIMEOUT; @@ -3409,21 +3414,16 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + processor_wait_timeout = DEFAULT_PROCESSOR_WAIT_TIMEOUT; + processor_wait_steps = DEFAULT_PROCESSOR_WAIT_STEPS; + -+ + apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + /* we need to know ServerLimit and ThreadLimit before we start processing + * the tree because we need to already have allocated child_info_table + */ -+ for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) -+ { -+ if (!strcasecmp(pdir->directive, "ServerLimit")) -+ { -+ if (atoi(pdir->args) > tmp_server_limit) -+ { ++ for (pdir = ap_conftree; pdir != NULL; pdir = pdir->next) { ++ if (!strcasecmp(pdir->directive, "ServerLimit")) { ++ if (atoi(pdir->args) > tmp_server_limit) { + tmp_server_limit = atoi(pdir->args); -+ if (tmp_server_limit > MAX_SERVER_LIMIT) -+ { ++ if (tmp_server_limit > MAX_SERVER_LIMIT) { + tmp_server_limit = MAX_SERVER_LIMIT; + } + } @@ -3442,9 +3442,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (!child_info_image) { + _DBG("Initializing child_info_table", 0); -+ child_info_size = tmp_server_limit * sizeof(child_info_t) + sizeof(apr_size_t); ++ child_info_size = tmp_server_limit * sizeof(child_info_t) ++ + sizeof(apr_size_t); + -+ rv = apr_shm_create(&child_info_shm, child_info_size, NULL, global_pool); ++ rv = apr_shm_create(&child_info_shm, child_info_size, NULL, ++ global_pool); + + /* if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) { */ + if (rv != APR_SUCCESS) { @@ -3464,38 +3466,42 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return HTTP_INTERNAL_SERVER_ERROR; + } + -+ memset(shmem, 0, child_info_size); -+ child_info_image = (child_info*)apr_palloc(global_pool, sizeof(child_info)); -+ child_info_image->control = (child_info_control*)shmem; ++ child_info_image = (child_info*) apr_palloc(global_pool, ++ sizeof(child_info)); ++ child_info_image->control = (child_info_control*) shmem; + shmem += sizeof(child_info_control); -+ child_info_image->table = (child_info_t*)shmem; -+ } -+ -+ _DBG("Clearing child_info_table"); -+ child_info_image->control->num = 0; ++ child_info_image->table = (child_info_t*) shmem; + -+ for (i = 0; i < tmp_server_limit; i++) { -+ CHILD_INFO_TABLE[i].pid = 0; -+ CHILD_INFO_TABLE[i].senv = (server_env_t*)NULL; -+ CHILD_INFO_TABLE[i].type = CHILD_TYPE_UNKNOWN; -+ CHILD_INFO_TABLE[i].status = CHILD_STATUS_STANDBY; -+ CHILD_INFO_TABLE[i].sock_fd = -3; /* -1 and -2 are taken */ -+ CHILD_INFO_TABLE[i].id = i; ++ for (i = 0; i < tmp_server_limit; i++) { ++ memset(&CHILD_INFO_TABLE[i], 0, sizeof(child_info_t)); ++ CHILD_INFO_TABLE[i].id = i; ++ } ++ } ++ else { ++ for (i = 0; i < NUM_CHILDS; i++) { ++ if (!is_graceful || (CHILD_INFO_TABLE[i].pid == 0 ++ && CHILD_INFO_TABLE[i].status == CHILD_STATUS_STANDBY)) { ++ memset(&CHILD_INFO_TABLE[i], 0, sizeof(child_info_t)); ++ CHILD_INFO_TABLE[i].id = i; ++ } ++ } + } + -+ if (!server_env_image) -+ { -+ _DBG("Initializing server_environments_table", 0); -+ server_env_size = tmp_server_limit * sizeof(server_env_t) + sizeof(apr_size_t); ++ if (!server_env_image) { ++ _DBG("Initializing server_environments_table", 0); + -+ rv = apr_shm_create(&server_env_shm, server_env_size, NULL, global_pool); ++ server_env_size = tmp_server_limit * sizeof(server_env_t) ++ + sizeof(apr_size_t); + -+ if (rv != APR_SUCCESS) { -+ _DBG("shared memory creation failed", 0); ++ rv = apr_shm_create(&server_env_shm, server_env_size, NULL, ++ global_pool); + -+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, -+ "Unable to create shared memory segment " -+ "(anonymous shared memory failure)"); ++ if (rv != APR_SUCCESS) { ++ _DBG("shared memory creation failed", 0); ++ ++ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, ++ "Unable to create shared memory segment " ++ "(anonymous shared memory failure)"); + } + else if (rv == APR_ENOTIMPL) { + _DBG("anonymous shared memory not available", 0); @@ -3508,38 +3514,39 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + + memset(shmem, 0, server_env_size); -+ server_env_image = (server_env*)apr_palloc(global_pool, sizeof(server_env)); -+ server_env_image->control = (server_env_control*)shmem; ++ server_env_image = (server_env*) apr_palloc(global_pool, ++ sizeof(server_env)); ++ server_env_image->control = (server_env_control*) shmem; + shmem += sizeof(server_env_control); -+ server_env_image->table = (server_env_t*)shmem; ++ server_env_image->table = (server_env_t*) shmem; + } -+ ++ + _DBG("Clearing server environment table"); -+ server_env_image->control->num = 0; ++ server_env_image->control->num = 0; + + for (i = 0; i < tmp_server_limit; i++) { + SENV[i].processor_id = -1; -+ SENV[i].uid = -1; -+ SENV[i].gid = -1; -+ SENV[i].chroot = NULL; -+ SENV[i].input = -1; -+ SENV[i].output = -1; ++ SENV[i].uid = -1; ++ SENV[i].gid = -1; ++ SENV[i].chroot = NULL; ++ SENV[i].input = -1; ++ SENV[i].output = -1; + SENV[i].error_cgroup = 0; -+ SENV[i].error_pass = 0; ++ SENV[i].error_pass = 0; + } + + return OK; +} + -+static int peruser_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *server_list) ++static int peruser_post_config(apr_pool_t *p, apr_pool_t *plog, ++ apr_pool_t *ptemp, server_rec *server_list) +{ -+ server_env_t senv; + const char *r; -+ -+ ap_child_table = (ap_ctable *)apr_pcalloc(p, server_limit * sizeof(ap_ctable)); ++ server_env_t senv; + + /* Retrieve the function from mod_ssl for detecting SSL virtualhosts */ -+ ssl_server_is_https = (ssl_server_is_https_t) apr_dynamic_fn_retrieve("ssl_server_is_https"); ++ ssl_server_is_https = (ssl_server_is_https_t) apr_dynamic_fn_retrieve( ++ "ssl_server_is_https"); + + /* Create the server environment for multiplexers */ + senv.uid = unixd_config.user_id; @@ -3548,17 +3555,20 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + senv.cgroup = NULL; + senv.nice_lvl = 0; + senv.name = "Multiplexer"; ++ senv.stats_connections = 0; ++ senv.stats_requests = 0; ++ senv.stats_dropped = 0; + -+ senv.min_processors = ap_min_multiplexers; -+ senv.min_free_processors = ap_min_free_processors; -+ senv.max_free_processors = ap_max_free_processors; -+ senv.max_processors = ap_max_multiplexers; ++ senv.min_processors = ap_min_multiplexers; ++ senv.min_free_processors = ap_min_free_processors; ++ senv.max_free_processors = ap_max_free_processors; ++ senv.max_processors = ap_max_multiplexers; + -+ r = child_add(CHILD_TYPE_MULTIPLEXER, CHILD_STATUS_STARTING, -+ p, &senv); ++ r = child_add(CHILD_TYPE_MULTIPLEXER, CHILD_STATUS_STARTING, p, ++ &senv); + + if (r != NULL) { -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, p, r); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, r); + return -1; + } + @@ -3573,33 +3583,34 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + child_info_t *processor; + + if (sconf->senv == NULL) { -+ _DBG("Server environment not set on virtualhost %s", r->server->server_hostname); ++ _DBG("Server environment not set on virtualhost %s", ++ r->server->server_hostname); + + if (sconf->missing_senv_reported == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, + "Virtualhost %s has no server environment set, " -+ "request will not be honoured.", r->server->server_hostname); ++ "request will not be honoured.", ++ r->server->server_hostname); + } -+ ++ + sconf->missing_senv_reported = 1; + + return HTTP_INTERNAL_SERVER_ERROR; + } + -+ if(CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) ++ if (CHILD_INFO_TABLE[my_child_num].type == CHILD_TYPE_MULTIPLEXER) { + processor = &CHILD_INFO_TABLE[sconf->senv->processor_id]; -+ else ++ } ++ else { + processor = &CHILD_INFO_TABLE[r->connection->id]; ++ } + -+ -+ if (!strlen(r->the_request)) -+ { ++ if (!strlen(r->the_request)) { + _DBG("corrupt request. aborting",0); + return DECLINED; + } + -+ if (processor->sock_fd != AP_PERUSER_THISCHILD) -+ { ++ if (processor->sock_fd != AP_PERUSER_THISCHILD) { + apr_socket_t *sock = NULL; + + apr_os_sock_put(&sock, &processor->sock_fd, r->connection->pool); @@ -3609,201 +3620,239 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return OK; + } + -+ switch (CHILD_INFO_TABLE[my_child_num].type) ++ switch (CHILD_INFO_TABLE[my_child_num].type) { ++ case CHILD_TYPE_MULTIPLEXER: + { -+ case CHILD_TYPE_MULTIPLEXER: -+ { -+ _DBG("MULTIPLEXER => Determining if request should be passed. " -+ "Child Num: %d, dest-child: %d, hostname from server: %s r->hostname=%s r->the_request=\"%s\"", -+ my_child_num, processor->id, r->server->server_hostname, r->hostname, r->the_request); ++ _DBG("MULTIPLEXER => Determining if request should be passed. " ++ "Child Num: %d, dest-child: %d, hostname from server: %s " ++ "r->hostname=%s r->the_request=\"%s\"", ++ my_child_num, processor->id, r->server->server_hostname, ++ r->hostname, r->the_request); ++ ++ if (processor->id != my_child_num) { ++ if (processor->status == CHILD_STATUS_STANDBY) { ++ _DBG("Activating child #%d", processor->id); ++ processor->status = CHILD_STATUS_STARTING; ++ } + -+ if (processor->id != my_child_num) -+ { -+ if (processor->status == CHILD_STATUS_STANDBY) -+ { -+ _DBG("Activating child #%d", processor->id); -+ processor->status = CHILD_STATUS_STARTING; ++ _DBG("Passing request.",0); ++ if (pass_request(r, processor) == -1) { ++ if (processor->senv->error_pass == 0) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, ++ "Could not pass request to processor %s " ++ "(virtualhost %s), " ++ "request will not be honoured.", ++ processor->senv->name, r->hostname); + } + -+ _DBG("Passing request.",0); -+ if (pass_request(r, processor) == -1) -+ { -+ if (processor->senv->error_pass == 0) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, -+ ap_server_conf, "Could not pass request to processor %s (virtualhost %s), request will not be honoured.", -+ processor->senv->name, r->hostname); -+ } ++ processor->senv->error_pass = 1; ++ processor->senv->stats_dropped++; ++ ++ return HTTP_SERVICE_UNAVAILABLE; ++ } ++ else { ++ processor->senv->error_pass = 0; ++ } + -+ processor->senv->error_pass = 1; ++ _DBG("doing longjmp",0); + -+ return HTTP_SERVICE_UNAVAILABLE; -+ } -+ else { -+ processor->senv->error_pass = 0; ++ longjmp(CHILD_INFO_TABLE[my_child_num].jmpbuffer, 1); ++ ++ _DBG("request declined at our site",0); ++ ++ return DECLINED; ++ } ++ ++ _DBG("The server is assigned to the multiplexer! Dropping request"); ++ ++ return DECLINED; ++ } ++ case CHILD_TYPE_PROCESSOR: ++ case CHILD_TYPE_WORKER: ++ { ++ if (sconf->senv != CHILD_INFO_TABLE[my_child_num].senv) { ++ _DBG("request not for this worker - passing it back to the " ++ "multiplexer"); ++ ++ child_info_t *multiplexer = &CHILD_INFO_TABLE[multiplexer_senv-> ++ processor_id]; ++ ++ if (pass_request(r, multiplexer) == -1) { ++ if (multiplexer->senv->error_pass == 0) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, ++ "Could not pass request to multiplexer, " ++ "request will not be honoured (%s).", ++ r->hostname); + } + -+ _DBG("doing longjmp",0); -+ longjmp(CHILD_INFO_TABLE[my_child_num].jmpbuffer, 1); -+ _DBG("request declined at our site",0); -+ return DECLINED; ++ multiplexer->senv->error_pass = 1; ++ multiplexer->senv->stats_dropped++; ++ ++ return HTTP_SERVICE_UNAVAILABLE; + } -+ _DBG("WTF: the server is assigned to the multiplexer! ... dropping request",0); ++ else { ++ multiplexer->senv->error_pass = 0; ++ } ++ _DBG("doing longjmp",0); ++ ++ longjmp(CHILD_INFO_TABLE[my_child_num].jmpbuffer, 1); ++ + return DECLINED; + } -+ case CHILD_TYPE_PROCESSOR: -+ case CHILD_TYPE_WORKER: -+ { -+ if (sconf->senv != CHILD_INFO_TABLE[my_child_num].senv) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, -+ 0, ap_server_conf, -+ "invalid virtualhost for this child! (%s)", r->hostname); -+ ap_lingering_close(r->connection); -+ return HTTP_REQUEST_TIME_OUT; -+ } -+ -+ _DBG("%s %d", child_type_string(CHILD_INFO_TABLE[my_child_num].type), my_child_num); -+ _DBG("request for %s / (server %s) seems to be for us", r->hostname, r->server->server_hostname); -+ -+ if (server_env_cleanup) -+ { -+ int i; -+ int input = sconf->senv->input; -+ int output = sconf->senv->output; + -+ _DBG("performing handle cleanup"); -+ for (i = 0; i < NUM_SENV; i++) -+ { -+ if (SENV[i].input > 0 && SENV[i].input != input) { -+ int retval = close(SENV[i].input); -+ if (retval < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, -+ "close(%d) failed", SENV[i].input); -+ } ++ _DBG("%s %d", child_type_string(CHILD_INFO_TABLE[my_child_num].type), ++ my_child_num); ++ ++ _DBG("request for %s / (server %s) seems to be for us", r->hostname, ++ r->server->server_hostname); ++ ++ if (server_env_cleanup) { ++ int i; ++ int input = sconf->senv->input; ++ int output = sconf->senv->output; ++ ++ _DBG("performing handle cleanup"); ++ for (i = 0; i < NUM_SENV; i++) { ++ if (&SENV[i] == multiplexer_senv) { ++ continue; ++ } ++ ++ if (SENV[i].input > 0 && SENV[i].input != input) { ++ int retval = close(SENV[i].input); ++ if (retval < 0) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ++ ap_server_conf, "close(%d) failed", ++ SENV[i].input); + } -+ if (SENV[i].output > 0 && SENV[i].output != output) { -+ int retval = close(SENV[i].output); -+ if (retval < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, -+ "close(%d) failed", SENV[i].output); -+ } ++ } ++ ++ if (SENV[i].output > 0 && SENV[i].output != output) { ++ int retval = close(SENV[i].output); ++ if (retval < 0) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ++ ap_server_conf, "close(%d) failed", ++ SENV[i].output); + } + } -+ server_env_cleanup = 0; + } -+ -+ return OK; -+ } -+ default: -+ { -+ _DBG("unspecified child type %d in %d, dropping request", -+ CHILD_INFO_TABLE[my_child_num].type, my_child_num); -+ return DECLINED; ++ server_env_cleanup = 0; + } ++ ++ CHILD_INFO_TABLE[my_child_num].senv->stats_requests++; ++ ++ return OK; ++ } ++ default: ++ { ++ _DBG("unspecified child type %d in %d, dropping request", ++ CHILD_INFO_TABLE[my_child_num].type, my_child_num); ++ return DECLINED; ++ } + } + + _DBG("THIS POINT SHOULD NOT BE REACHED!",0); ++ + return OK; +} + ++int senv_active_cmp(const void *a, const void *b) ++{ ++ _DBG("CMP %d %d", *(int *) a,*(int *) b); + -+int senv_active_cmp(const void *a, const void *b) { -+ _DBG("CMP %d %d", *(int *) a,*(int *) b); -+ return active_env_processors(*(int *)a)<active_env_processors(*(int *)b); ++ return active_env_processors(*(int *) a) ++ < active_env_processors(*(int *) b); +} + +static int peruser_status_hook(request_rec *r, int flags) +{ + int x; ++ child_info_t *child; + server_env_t *senv; + -+ if (flags & AP_STATUS_SHORT) -+ return OK; -+ -+ -+ if (flags & AP_STATUS_STATS) { -+ -+ int *sorted_senv; -+ int i; -+ sorted_senv=(int *) apr_palloc(r->pool, NUM_SENV*sizeof(int)); -+ -+ if(!sorted_senv) { -+ ap_rputs("peruser_status_hook(): Out of memory",r); -+ return OK; -+ } -+ /* Initial senv table */ -+ for(i=0; i < NUM_SENV; i++) -+ sorted_senv[i]=i; -+ -+ /* sort env by number of processors */ -+ qsort(sorted_senv, NUM_SENV, sizeof(int), senv_active_cmp); -+ -+ ap_rputs("<h3>Processors statistics:</h3><table border=\"0\"><tr><th>Environment</th><th>Pss</th><th>Avail</th></tr>", r); -+ /* just a mockup to se what data will be usefull here will put code layter, yes I know we need to iterate ON ENV[] NUM_ENV times */ -+ for (x = 0; x < NUM_SENV; x++) -+ { -+ senv = &SENV[sorted_senv[x]]; -+ if(senv==NULL) -+ continue; -+ ap_rprintf(r, "<tr><td nowrap>%s</td><td nowrap>%d/%d/%d</td>" -+ "<td>%d%%</td></tr>", -+ senv == NULL ? NULL : ( senv->name == NULL ? "" : senv->name ), -+ active_env_processors(sorted_senv[x]), idle_env_processors(sorted_senv[x]), senv == NULL ? 0 : senv->max_processors, -+ senv == NULL ? 0 : senv->availability ); -+ } -+ ap_rputs("</table><tr/>", r); -+ -+ ap_rputs("<hr/><table>" -+ "<tr><th>Pss</th><td>Number of processors active/idle/max</td></tr>" -+ "</table><hr/>",r); -+ }else { -+ ap_rputs("<hr>\n", r); -+ ap_rputs("<h3>peruser status</h3>\n", r); -+ ap_rputs("<table border=\"0\">\n", r); -+ ap_rputs("<tr><th>ID</th><th>PID</th><th>STATUS</th><th>SB STATUS</th><th>Type</th><th>Processor</th>" -+ "<th>Pss</th>" -+ "<th>AVAIL</th>" -+ "</tr>\n", r); -+ for (x = 0; x < NUM_CHILDS; x++) -+ { -+ senv = CHILD_INFO_TABLE[x].senv; -+ ap_rprintf(r, "<tr><td>%3d</td><td>%5d</td><td>%8s</td><td>%8s</td><td>%12s</td><td nowrap>%48s</td>" -+ "<td>%d/%d/%d</td>" ++ if (flags & AP_STATUS_SHORT) { ++ return OK; ++ } ++ ++ if (flags & AP_STATUS_PERUSER_STATS) { ++ int *sorted_senv; ++ int i; ++ sorted_senv = (int *) apr_palloc(r->pool, NUM_SENV * sizeof(int)); ++ ++ if (!sorted_senv) { ++ ap_rputs("peruser_status_hook(): Out of memory", r); ++ return OK; ++ } ++ ++ /* Initial senv table */ ++ for (i = 0; i < NUM_SENV; i++) { ++ sorted_senv[i] = i; ++ } ++ ++ /* sort env by number of processors */ ++ qsort(sorted_senv, NUM_SENV, sizeof(int), senv_active_cmp); ++ ++ ap_rputs("<h3>Processors statistics:</h3>" ++ "<table width=700 border=\"0\"><tr><th>Environment</th><th>Pss</th>" ++ "<th>Connections</th><th>Requests</th><th>Dropped (503)</th>" ++ "<th>Avail</th></tr>", r); ++ ++ /* just a mockup to see what data will be useful here will put code ++ * later, yes I know we need to iterate ON ENV[] NUM_ENV times */ ++ for (x = 0; x < NUM_SENV; x++) { ++ senv = &SENV[sorted_senv[x]]; ++ if (senv == NULL) { ++ continue; ++ } ++ ++ ap_rprintf(r, "<tr><td nowrap>%s</td><td nowrap>%d/%d/%d</td>" ++ "<td>%d</td><td>%d</td><td>%d</td><td>%d%%</td></tr>", ++ senv->name == NULL ? "" : senv->name, ++ active_env_processors(sorted_senv[x]), ++ idle_env_processors(sorted_senv[x]), ++ senv->max_processors, senv->stats_connections, ++ senv->stats_requests, senv->stats_dropped, ++ senv->availability); ++ } ++ ap_rputs("</table><tr/>", r); ++ ++ ap_rputs("<hr/><table>" ++ "<tr><th>Pss</th><td>Number of processors active/idle/max</td></tr>" ++ "</table><hr/>", r); ++ } ++ else { ++ ap_rputs("<hr>\n", r); ++ ap_rputs("<h3>peruser status</h3>\n", r); ++ ap_rputs("<table border=\"0\">\n", r); ++ ap_rputs("<tr><th>ID</th><th>PID</th><th>STATUS</th><th>SB STATUS</th>" ++ "<th>Type</th><th>Processor</th><th>Pss</th><th>AVAIL</th>" ++ "</tr>\n", r); ++ ++ for (x = 0; x < NUM_CHILDS; x++) { ++ child = &CHILD_INFO_TABLE[x]; ++ senv = child->senv; ++ ap_rprintf(r, ++ "<tr><td>%3d</td><td>%5d</td><td>%8s</td><td>%8s</td>" ++ "<td>%12s</td><td nowrap>%48s</td><td>%d/%d/%d</td>" + "<td>%3d%%</td></tr>\n", -+ CHILD_INFO_TABLE[x].id, -+ CHILD_INFO_TABLE[x].pid, -+ child_status_string(CHILD_INFO_TABLE[x].status), ++ child->id, child->pid, ++ child_status_string(child->status), + scoreboard_status_string(SCOREBOARD_STATUS(x)), -+ child_type_string(CHILD_INFO_TABLE[x].type), -+ senv == NULL ? NULL : ( senv->name == NULL ? "" : senv->name ), ++ child_type_string(child->type), ++ senv == NULL ? NULL : (senv->name == NULL ? "" : ++ senv->name), + active_processors(x), + idle_processors(x), -+ senv == NULL ? 0 : CHILD_INFO_TABLE[x].senv->max_processors, -+ senv == NULL ? 0 : CHILD_INFO_TABLE[x].senv->availability -+ ); -+ } -+ ap_rputs("</table>\n", r); -+ -+ ap_rputs("<hr/><table>" -+ "<tr><th>STATUS</th><td>Processor status</td></tr>" -+ "<tr><th>Pss</th><td>Number of processors active/idle/max</td></tr>" -+ "</table><hr/>",r); -+ } -+ -+ if (grace_children > 0) { -+ ap_rputs("<h2>peruser graceful children status</h2>\n", r); -+ ap_rprintf(r, "%d of total %d still living<br />\n", grace_children_alive, grace_children); -+ ap_rputs("<table border=\"0\">\n", r); -+ ap_rputs("<tr><td>ID</td><td>PID</td><td>STATUS</td><td>TYPE</td></tr>\n", r); -+ for (x = 0; x < grace_children; x++) { -+ ap_rprintf(r, "<tr><td>%3d</td><td>%5d</td><td>%8s</td><td>%12s</td></tr>\n", -+ child_grace_info_table[x].id, -+ child_grace_info_table[x].pid, -+ child_status_string(child_grace_info_table[x].status), -+ child_type_string(child_grace_info_table[x].type) -+ ); ++ senv == NULL ? 0 : senv->max_processors, ++ senv == NULL ? 0 : senv->availability); + } + ap_rputs("</table>\n", r); ++ ++ ap_rputs("<hr/><table>" ++ "<tr><th>STATUS</th><td>Processor status</td></tr>" ++ "<tr><th>Pss</th><td>Number of processors active/idle/max</td></tr>" ++ "</table><hr/>", r); + } ++ + return OK; +} + @@ -3813,7 +3862,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + * will be redirected to a file, and the messages won't print to the + * console. + */ -+ static const char *const aszSucc[] = {"core.c", NULL}; ++ static const char * const aszSucc[] = { "core.c", NULL }; + +#ifdef AUX3 + (void) set42sig(); @@ -3835,17 +3884,24 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + ap_hook_process_connection(peruser_process_connection, NULL, NULL, + APR_HOOK_REALLY_FIRST); + -+ APR_OPTIONAL_HOOK(ap, status_hook, peruser_status_hook, NULL, NULL, APR_HOOK_MIDDLE); ++ APR_OPTIONAL_HOOK(ap, status_hook, peruser_status_hook, NULL, NULL, ++ APR_HOOK_MIDDLE); +} + -+void senv_init(server_env_t * senv) { -+ senv->nice_lvl = 0; -+ senv->chroot = NULL; -+ senv->cgroup = NULL; -+ senv->min_processors = ap_min_processors; -+ senv->min_free_processors = ap_min_free_processors; -+ senv->max_free_processors = ap_max_free_processors; -+ senv->max_processors = ap_max_processors; ++void senv_init(server_env_t * senv) ++{ ++ senv->nice_lvl = 0; ++ senv->chroot = NULL; ++ senv->cgroup = NULL; ++ senv->min_processors = ap_min_processors; ++ senv->min_free_processors = ap_min_free_processors; ++ senv->max_free_processors = ap_max_free_processors; ++ senv->max_processors = ap_max_processors; ++ senv->error_cgroup = 0; ++ senv->error_pass = 0; ++ senv->stats_connections = 0; ++ senv->stats_requests = 0; ++ senv->stats_dropped = 0; +} + +static const char *cf_Processor(cmd_parms *cmd, void *dummy, const char *arg) @@ -3857,15 +3913,17 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + const char *endp = ap_strrchr_c(arg, '>'); + + if (endp == NULL) { -+ return apr_psprintf(cmd->temp_pool, -+ "Error: Directive %s> missing closing '>'", cmd->cmd->name); ++ return apr_psprintf(cmd->temp_pool, ++ "Error: Directive %s> missing closing '>'", ++ cmd->cmd->name); + } + + arg = apr_pstrndup(cmd->pool, arg, endp - arg); + + if (!arg) { -+ return apr_psprintf(cmd->temp_pool, -+ "Error: %s> must specify a processor name", cmd->cmd->name); ++ return apr_psprintf(cmd->temp_pool, ++ "Error: %s> must specify a processor name", ++ cmd->cmd->name); + } + + senv.name = ap_getword_conf(cmd->pool, &arg); @@ -3873,7 +3931,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (strlen(senv.name) == 0) { + return apr_psprintf(cmd->temp_pool, -+ "Error: Directive %s> takes one argument", cmd->cmd->name); ++ "Error: Directive %s> takes one argument", ++ cmd->cmd->name); + } + + server_env_t *old_senv = find_senv_by_name(senv.name); @@ -3888,27 +3947,28 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + current = cmd->directive->first_child; + + int proc_temp = 0; -+ for(; current != NULL; current = current->next) { ++ for (; current != NULL; current = current->next) { + directive = current->directive; -+ ++ + if (!strcasecmp(directive, "user")) { + user_name = current->args; + } + else if (!strcasecmp(directive, "group")) { -+ group_name = current->args; ++ group_name = current->args; + } + else if (!strcasecmp(directive, "chroot")) { + senv.chroot = ap_getword_conf(cmd->pool, ¤t->args); + } + else if (!strcasecmp(directive, "nicelevel")) { -+ senv.nice_lvl = atoi(current->args); ++ senv.nice_lvl = atoi(current->args); + } + else if (!strcasecmp(directive, "maxprocessors")) { + proc_temp = atoi(current->args); + + if (proc_temp < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: Require MaxProcessors > 0, setting to 1"); ++ "WARNING: Require MaxProcessors > 0," ++ "setting to 1"); + proc_temp = 1; + } + @@ -3919,7 +3979,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (proc_temp < 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: Require MinProcessors >= 0, setting to 0"); ++ "WARNING: Require MinProcessors >= 0," ++ "setting to 0"); + proc_temp = 0; + } + @@ -3930,7 +3991,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (proc_temp < 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: Require MinSpareProcessors >= 0, setting to 0"); ++ "WARNING: Require MinSpareProcessors >= 0," ++ "setting to 0"); + proc_temp = 0; + } + @@ -3938,10 +4000,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + else if (!strcasecmp(directive, "maxspareprocessors")) { + proc_temp = atoi(current->args); -+ ++ + if (proc_temp < 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: Require MaxSpareProcessors >= 0, setting to 0"); ++ "WARNING: Require MaxSpareProcessors >= 0," ++ "setting to 0"); + proc_temp = 0; + } + @@ -3952,53 +4015,64 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + } + else { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "Unknown directive %s in %s>", directive, cmd->cmd->name); ++ "Unknown directive %s in %s>", directive, ++ cmd->cmd->name); + } + } + + if (user_name == NULL || group_name == NULL) { + return apr_psprintf(cmd->temp_pool, -+ "Error: User or Group must be set in %s>", cmd->cmd->name); ++ "Error: User or Group must be set in %s>", ++ cmd->cmd->name); + } + + senv.uid = ap_uname2id(user_name); + senv.gid = ap_gname2id(group_name); + + _DBG("name=%s user=%s:%d group=%s:%d chroot=%s nice_lvl=%d", -+ senv.name, user_name, senv.uid, group_name, senv.gid, senv.chroot, senv.nice_lvl); ++ senv.name, user_name, senv.uid, group_name, senv.gid, senv.chroot, ++ senv.nice_lvl); + -+ _DBG("min_processors=%d min_free_processors=%d max_spare_processors=%d max_processors=%d", -+ senv.min_processors, senv.min_free_processors, senv.max_free_processors, senv.max_processors); ++ _DBG("min_processors=%d min_free_processors=%d max_spare_processors=%d " ++ "max_processors=%d", senv.min_processors, senv.min_free_processors, ++ senv.max_free_processors, senv.max_processors); + -+ return child_add(CHILD_TYPE_PROCESSOR, CHILD_STATUS_STANDBY, -+ cmd->pool, &senv); ++ return child_add(CHILD_TYPE_PROCESSOR, CHILD_STATUS_STANDBY, cmd->pool, ++ &senv); +} + +static const char *cf_Processor_depr(cmd_parms *cmd, void *dummy, -+ const char *user_name, const char *group_name, const char *chroot) ++ const char *user_name, ++ const char *group_name, const char *chroot) +{ + return NULL; +} + +/* we define an Multiplexer child w/ specific uid/gid */ +static const char *cf_Multiplexer(cmd_parms *cmd, void *dummy, -+ const char *user_name, const char *group_name, const char *chroot) ++ const char *user_name, const char *group_name, ++ const char *chroot) +{ + static short depr_warned = 0; -+ ++ + if (depr_warned == 0) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: Multiplexer directive is deprecated. Multiplexer user and group is set by User and Group directives."); -+ ++ "WARNING: Multiplexer directive is deprecated." ++ "Multiplexer user and group is set by User and Group" ++ "directives."); ++ + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "To set multiplexer chroot, please use MultiplexerChroot."); ++ "To set multiplexer chroot, " ++ "please use MultiplexerChroot."); + + depr_warned = 1; + } + + if (chroot) { -+ if (!ap_is_directory(cmd->pool, chroot)) -+ return apr_psprintf(cmd->pool, "Error: multiplexer chroot directory [%s] does not exist", chroot); ++ if (!ap_is_directory(cmd->pool, chroot)) { ++ return apr_psprintf(cmd->pool, "Error:multiplexer chroot directory" ++ "[%s] does not exist", chroot); ++ } + + multiplexer_chroot = chroot; + _DBG("Setting multiplexer chroot to %s", chroot); @@ -4008,12 +4082,13 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +} + +static const char* cf_MultiplexerChroot(cmd_parms *cmd, void *dummy, -+ const char *path) ++ const char *path) +{ + multiplexer_chroot = path; + + if (path && !ap_is_directory(cmd->pool, path)) -+ return apr_psprintf(cmd->pool, "Error: multiplexer chroot directory [%s] does not exist", path); ++ return apr_psprintf(cmd->pool, "Error: multiplexer chroot directory" ++ "[%s] does not exist", path); + + _DBG("setting multiplexer chroot to %s", path); + @@ -4021,108 +4096,117 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +} + +static const char* cf_ServerEnvironment(cmd_parms *cmd, void *dummy, -+ const char *name, const char * group_name, const char * chroot) ++ const char *name, const char * group_name, const char * chroot) +{ + peruser_server_conf *sconf = PERUSER_SERVER_CONF(cmd->server->module_config); + server_env_t senv; + char * processor_name, *tmp; -+ ++ + _DBG("function entered", 0); -+ ++ + /* name of processor env */ + processor_name = name; -+ -+ if(group_name != NULL || chroot != NULL) { ++ ++ if (group_name != NULL || chroot != NULL) { + /* deprecated ServerEnvironment user group chroot syntax + * we create simple server env based on user/group/chroot only + */ -+ processor_name = apr_pstrcat(cmd->pool, name, "_",group_name, "_", chroot, NULL); -+ ++ processor_name = apr_pstrcat(cmd->pool, name, "_", group_name, "_", ++ chroot, NULL); ++ + /* search for previous default server env */ + sconf->senv = find_senv_by_name(processor_name); -+ -+ if(!sconf->senv) { ++ ++ if (!sconf->senv) { + senv_init(&senv); + senv.uid = ap_uname2id(name); + senv.gid = ap_gname2id(group_name); + senv.chroot = chroot; + senv.name = processor_name; -+ -+ tmp = child_add(CHILD_TYPE_PROCESSOR, CHILD_STATUS_STANDBY, cmd->pool, &senv); ++ ++ tmp = child_add(CHILD_TYPE_PROCESSOR, CHILD_STATUS_STANDBY, ++ cmd->pool, &senv); + /* error handling in case this child can't be created */ -+ if(tmp) ++ if (tmp) { + return tmp; ++ } + } + } -+ ++ + /* use predefined processor environment or default named "user_group_chroot" */ -+ if(sconf->senv == NULL) ++ if (sconf->senv == NULL) { + sconf->senv = find_senv_by_name(processor_name); -+ ++ } ++ + if (sconf->senv == NULL) { -+ return apr_psprintf(cmd->pool, -+ "Error: Processor %s not defined", name); ++ return apr_psprintf(cmd->pool, "Error: Processor %s not defined", name); + } + + _DBG("user=%d group=%d chroot=%s numchilds=%d", -+ sconf->senv->uid, sconf->senv->gid, sconf->senv->chroot, NUM_CHILDS); ++ sconf->senv->uid, sconf->senv->gid, sconf->senv->chroot, NUM_CHILDS); + + return NULL; +} + -+static const char *set_min_free_servers(cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_min_free_servers(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); ++ + if (err != NULL) { + return err; + } + + ap_min_free_processors = atoi(arg); + if (ap_min_free_processors <= 0) { -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: detected MinSpareServers set to non-positive."); -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "Resetting to 1 to avoid almost certain Apache failure."); -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "Please read the documentation."); -+ ap_min_free_processors = 1; -+ } -+ ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: detected MinSpareServers set to non-positive."); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "Resetting to 1 to avoid almost certain Apache failure."); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "Please read the documentation."); ++ ap_min_free_processors = 1; ++ } ++ + return NULL; +} + -+static const char *set_max_clients (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_max_clients(cmd_parms *cmd, void *dummy, const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); ++ + if (err != NULL) { + return err; + } + + ap_daemons_limit = atoi(arg); ++ + if (ap_daemons_limit > server_limit) { -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: MaxClients of %d exceeds ServerLimit value " -+ "of %d servers,", ap_daemons_limit, server_limit); -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ " lowering MaxClients to %d. To increase, please " -+ "see the ServerLimit", server_limit); -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ " directive."); -+ ap_daemons_limit = server_limit; -+ } ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: MaxClients of %d exceeds ServerLimit value " ++ "of %d servers,", ap_daemons_limit, server_limit); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ " lowering MaxClients to %d. To increase, please " ++ "see the ServerLimit", server_limit); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, " directive."); ++ ap_daemons_limit = server_limit; ++ } + else if (ap_daemons_limit < 1) { -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require MaxClients > 0, setting to 1"); -+ ap_daemons_limit = 1; ++ ap_daemons_limit = 1; + } ++ + return NULL; +} + -+static const char *set_min_processors (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_min_processors(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ + peruser_server_conf *sconf; + int min_procs; -+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); ++ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE ++ | NOT_IN_LIMIT); + + if (err != NULL) { + return err; @@ -4138,24 +4222,28 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST) != NULL) { + sconf = PERUSER_SERVER_CONF(cmd->server->module_config); -+ if(sconf->senv != NULL) -+ sconf->senv->min_processors = min_procs; -+ else -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: MinProcessors must be set after ServerEnvironment to take effect"); -+ } -+ else { ++ ++ if (sconf->senv != NULL) { ++ sconf->senv->min_processors = min_procs; ++ } else { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: MinProcessors must be set" ++ "after ServerEnvironment to take effect"); ++ } ++ } else { + ap_min_processors = min_procs; + } + + return NULL; +} + -+static const char *set_min_free_processors (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_min_free_processors(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ + peruser_server_conf *sconf; + int min_free_procs; -+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); ++ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE ++ | NOT_IN_LIMIT); + + if (err != NULL) { + return err; @@ -4171,57 +4259,64 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST) != NULL) { + sconf = PERUSER_SERVER_CONF(cmd->server->module_config); -+ if(sconf->senv != NULL) -+ sconf->senv->min_free_processors = min_free_procs; -+ else -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: MinSpareProcessors must be set after ServerEnvironment to take effect"); -+ } -+ else { ++ if (sconf->senv != NULL) { ++ sconf->senv->min_free_processors = min_free_procs; ++ } else { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: MinSpareProcessors must be set" ++ "after ServerEnvironment to take effect"); ++ } ++ } else { + ap_min_free_processors = min_free_procs; + } + + return NULL; +} + -+static const char *set_max_free_processors (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_max_free_processors(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ -+ peruser_server_conf *sconf; -+ int max_free_procs; -+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); -+ -+ if (err != NULL) { -+ return err; -+ } -+ -+ max_free_procs = atoi(arg); -+ -+ if (max_free_procs < 0) { -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: Require MaxSpareProcessors >= 0, setting to 0"); -+ max_free_procs = 0; -+ } -+ -+ if (ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST) != NULL) { -+ sconf = PERUSER_SERVER_CONF(cmd->server->module_config); -+ if(sconf!=NULL) -+ sconf->senv->max_free_processors = max_free_procs; -+ else -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: MaxSpareProcessors must be set after ServerEnvironment to take effect"); -+ } -+ else { -+ ap_max_free_processors = max_free_procs; -+ } -+ -+ return NULL; ++ peruser_server_conf *sconf; ++ int max_free_procs; ++ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE ++ | NOT_IN_LIMIT); ++ ++ if (err != NULL) { ++ return err; ++ } ++ ++ max_free_procs = atoi(arg); ++ ++ if (max_free_procs < 0) { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: Require MaxSpareProcessors >= 0, setting to 0"); ++ max_free_procs = 0; ++ } ++ ++ if (ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST) != NULL) { ++ sconf = PERUSER_SERVER_CONF(cmd->server->module_config); ++ ++ if (sconf != NULL) { ++ sconf->senv->max_free_processors = max_free_procs; ++ } else { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: MaxSpareProcessors must be set" ++ "after ServerEnvironment to take effect"); ++ } ++ } else { ++ ap_max_free_processors = max_free_procs; ++ } ++ ++ return NULL; +} + -+static const char *set_max_processors (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_max_processors(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ + peruser_server_conf *sconf; + int max_procs; -+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); ++ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE ++ | NOT_IN_LIMIT); + + if (err != NULL) { + return err; @@ -4237,23 +4332,26 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST) != NULL) { + sconf = PERUSER_SERVER_CONF(cmd->server->module_config); -+ if(sconf->senv != NULL) -+ sconf->senv->max_processors = max_procs; -+ else -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: MaxProcessors must be set after ServerEnvironment to take effect"); -+ } -+ else { ++ if (sconf->senv != NULL) { ++ sconf->senv->max_processors = max_procs; ++ } else { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: MaxProcessors must be set" ++ "after ServerEnvironment to take effect"); ++ } ++ } else { + ap_max_processors = max_procs; + } + + return NULL; +} + -+static const char *set_min_multiplexers (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_min_multiplexers(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ + int min_multiplexers; -+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); ++ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE ++ | NOT_IN_LIMIT); + + if (err != NULL) { + return err; @@ -4272,10 +4370,12 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return NULL; +} + -+static const char *set_max_multiplexers (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_max_multiplexers(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ + int max_multiplexers; -+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); ++ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE ++ | NOT_IN_LIMIT); + + if (err != NULL) { + return err; @@ -4294,21 +4394,22 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return NULL; +} + -+static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) ++static const char *set_server_limit(cmd_parms *cmd, void *dummy, ++ const char *arg) +{ + int tmp_server_limit; -+ ++ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + tmp_server_limit = atoi(arg); ++ + /* you cannot change ServerLimit across a restart; ignore + * any such attempts + */ -+ if (first_server_limit && -+ tmp_server_limit != server_limit) { ++ if (first_server_limit && tmp_server_limit != server_limit) { + /* how do we log a message? the error log is a bit bucket at this + * point; we'll just have to set a flag so that ap_mpm_run() + * logs a warning later @@ -4316,25 +4417,28 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + changed_limit_at_restart = 1; + return NULL; + } ++ + server_limit = tmp_server_limit; -+ ++ + if (server_limit > MAX_SERVER_LIMIT) { -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: ServerLimit of %d exceeds compile time limit " -+ "of %d servers,", server_limit, MAX_SERVER_LIMIT); -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); -+ server_limit = MAX_SERVER_LIMIT; -+ } -+ else if (server_limit < 1) { -+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: ServerLimit of %d exceeds compile time limit " ++ "of %d servers,", server_limit, MAX_SERVER_LIMIT); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); ++ server_limit = MAX_SERVER_LIMIT; ++ } else if (server_limit < 1) { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + "WARNING: Require ServerLimit > 0, setting to 1"); -+ server_limit = 1; ++ server_limit = 1; + } ++ + return NULL; +} + -+static const char *set_expire_timeout (cmd_parms *cmd, void *dummy, const char *arg) { ++static const char *set_expire_timeout(cmd_parms *cmd, void *dummy, ++ const char *arg) ++{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; @@ -4345,7 +4449,9 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return NULL; +} + -+static const char *set_idle_timeout (cmd_parms *cmd, void *dummy, const char *arg) { ++static const char *set_idle_timeout(cmd_parms *cmd, void *dummy, ++ const char *arg) ++{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; @@ -4356,7 +4462,9 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return NULL; +} + -+static const char *set_multiplexer_idle_timeout (cmd_parms *cmd, void *dummy, const char *arg) { ++static const char *set_multiplexer_idle_timeout(cmd_parms *cmd, void *dummy, ++ const char *arg) ++{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + + if (err != NULL) { @@ -4368,9 +4476,12 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return NULL; +} + -+static const char *set_processor_wait_timeout (cmd_parms *cmd, void *dummy, const char *timeout, const char *steps) { ++static const char *set_processor_wait_timeout(cmd_parms *cmd, void *dummy, ++ const char *timeout, ++ const char *steps) ++{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); -+ ++ + if (err != NULL) { + return err; + } @@ -4382,7 +4493,8 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + + if (steps_tmp < 1) { + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, -+ "WARNING: Require ProcessorWaitTimeout steps > 0, setting to 1"); ++ "WARNING: Require ProcessorWaitTimeout steps > 0," ++ "setting to 1"); + steps_tmp = 1; + } + @@ -4392,8 +4504,7 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + return NULL; +} + -+static const command_rec peruser_cmds[] = { -+UNIX_DAEMON_COMMANDS, ++static const command_rec peruser_cmds[] = { UNIX_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1("MinSpareProcessors", set_min_free_processors, NULL, RSRC_CONF, + "Minimum number of idle children, to handle request spikes"), @@ -4407,8 +4518,9 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + "Minimum number of processors per vhost"), +AP_INIT_TAKE1("MaxProcessors", set_max_processors, NULL, RSRC_CONF, + "Maximum number of processors per vhost"), ++ +AP_INIT_TAKE1("MinMultiplexers", set_min_multiplexers, NULL, RSRC_CONF, -+ "Minimum number of multiplexers the server can have"), ++ "Minimum number of multiplexers the server can have") , +AP_INIT_TAKE1("MaxMultiplexers", set_max_multiplexers, NULL, RSRC_CONF, + "Maximum number of multiplexers the server can have"), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, @@ -4416,11 +4528,14 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ +AP_INIT_TAKE1("ExpireTimeout", set_expire_timeout, NULL, RSRC_CONF, + "Maximum time a child can live, 0 to disable"), +AP_INIT_TAKE1("IdleTimeout", set_idle_timeout, NULL, RSRC_CONF, -+ "Maximum time before a child is killed after being idle, 0 to disable"), -+AP_INIT_TAKE1("MultiplexerIdleTimeout", set_multiplexer_idle_timeout, NULL, RSRC_CONF, -+ "Maximum time before a multiplexer is killed after being idle, 0 to disable"), -+AP_INIT_TAKE12("ProcessorWaitTimeout", set_processor_wait_timeout, NULL, RSRC_CONF, -+ "Maximum time a multiplexer waits for the processor if it is busy"), ++ "Maximum time before a child is killed after being idle," ++ "0 to disable"), ++AP_INIT_TAKE1("MultiplexerIdleTimeout", set_multiplexer_idle_timeout, NULL, ++ RSRC_CONF, "Maximum time before a multiplexer is killed after" ++ " being idle, 0 to disable"), ++AP_INIT_TAKE12("ProcessorWaitTimeout", set_processor_wait_timeout, NULL, ++ RSRC_CONF, "Maximum time a multiplexer waits for the processor" ++ " if it is busy"), +AP_INIT_TAKE23("Multiplexer", cf_Multiplexer, NULL, RSRC_CONF, + "Specify an Multiplexer Child configuration."), +AP_INIT_RAW_ARGS("<Processor", cf_Processor, NULL, RSRC_CONF, @@ -4436,11 +4551,11 @@ diff -ruN httpd-2.2.14/server/mpm/experimental/peruser/peruser.c peruser-0.4rc1/ + +module AP_MODULE_DECLARE_DATA mpm_peruser_module = { + MPM20_MODULE_STUFF, -+ ap_mpm_rewrite_args, /* hook to run before apache parses args */ -+ NULL, /* create per-directory config structure */ -+ NULL, /* merge per-directory config structures */ -+ peruser_create_config, /* create per-server config structure */ -+ NULL, /* merge per-server config structures */ -+ peruser_cmds, /* command apr_table_t */ -+ peruser_hooks, /* register hooks */ ++ ap_mpm_rewrite_args, /* hook to run before apache parses args */ ++ NULL, /* create per-directory config structure */ ++ NULL, /* merge per-directory config structures */ ++ peruser_create_config, /* create per-server config structure */ ++ NULL, /* merge per-server config structures */ ++ peruser_cmds, /* command apr_table_t */ ++ peruser_hooks, /* register hooks */ +}; |