From: Ryan Bloom Date: Thu, 1 Feb 2001 21:55:16 +0000 (+0000) Subject: Bring mod_status for 2.0 back in line with mod_status for 1.3. This is X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=23d8ef446582e9809f0f25f9f1ca1a4aeea94453;p=apache Bring mod_status for 2.0 back in line with mod_status for 1.3. This is basically a straight port of the 1.3 module to 2.0. The MPMs need to be modified a bit to work with mod_status, but prefork, mpmt_pthread, and dexter have already been changed. I will fix perchild tonight. There is a lot of common code that can be abstracted, and there seems to be a small bug with regard to what mpmt_pthread and dexter report as current connections. ExtendedStatus does work again, although until the bug mentioned above is fixed, it isn't as useful on mpmt_pthread and dexter. Next week, I will look at allowing other modules to add data to the STATUS page and possibly to the scoreboard itself. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@87949 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 40866bca4d..2b9f3c2d70 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ Changes with Apache 2.0b1 + *) Make mod_status work with 2.0. This will work for prefork, + mpmt_pthread, and dexter. [Ryan Bloom] + *) Correct a typo in httpd.conf. [Kunihiro Tanaka ] PR#7154 diff --git a/include/mpm_status.h b/include/mpm_status.h deleted file mode 100644 index aa222b9012..0000000000 --- a/include/mpm_status.h +++ /dev/null @@ -1,137 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - */ - -/* - * TODO: Possible additions to this API include getting a list of connection - * IDs and a list of keys in a particular row. - */ - -#ifndef APACHE_MPM_STATUS_H -#define APACHE_MPM_STATUS_H - -#include "apr_lib.h" - -/** - * @package MPM Status API - */ - -typedef struct ap_status_table_row_t ap_status_table_row_t; -/** - * The MPM status table row structure. MPMs should use this structure in - * a table to store the status for the requests. This structure stores the - * status for one connection - */ -struct ap_status_table_row_t { - /** The connection id. This is used as a key for the status table */ - long conn_id; - /** The actual status. This is a table of key-value pairs */ - apr_table_t *data; -}; - -/** - * Get a cell from the status table. Don't mess with the string you get. - * @param conn_id Connection ID of the current connection - * @param key The key to determine which status value should be retrieved - * for the connection. - * @deffunc const char *ap_get_connection_status(long conn_id, const char *key) - */ -AP_DECLARE(const char *) ap_get_connection_status(long conn_id, const char *key); - -/** - * Get an array of current connection IDs. - * @param p The pool to allocate the array out of - * @return An array of all the current connection IDs - * @deffunc apr_array_header_t *ap_get_connections(apr_pool_t *p) - */ -AP_DECLARE(apr_array_header_t *) ap_get_connections(apr_pool_t *p); - -/** - * Get an array of keys from a given connection. - * @param p Pool to allocate out of - * @param conn_id Connection ID to get the keys for - * @return an array of keys from a given connection - * @deffunc apr_array_header_t *ap_get_connection_keys(apr_pool_t *p, long conn_id) - */ -AP_DECLARE(apr_array_header_t *) ap_get_connection_keys(apr_pool_t *p, - long conn_id); - -/** - * Set a cell in the status table. No guarantees are made that long strings - * won't be truncated. - * @param conn_id Connection ID to update - * @param key key to update - * @param value value to set for the key - * @deffunc void ap_update_connection_status(long conn_id, const char *key, const char *value) - */ -AP_DECLARE(void) ap_update_connection_status(long conn_id, const char *key, const char *value); - -/** - * Clear out this connection's status values. Normally called when a - * connection is closed - * @param conn_id The connection ID to clear - * @deffunc void ap_reset_connection_status(long conn_id) - */ -AP_DECLARE(void) ap_reset_connection_status(long conn_id); - -/** - * Returns the most up-to-date status table available, in the form of an array - * of ap_status_row_t's. - * @param p pool to allocate the array out of, generally from the request_rec - * @return The table of statuses for all connections - * @deffunc apr_array_header_t *ap_get_status_table(apr_pool_t *p) - */ -AP_DECLARE(apr_array_header_t *) ap_get_status_table(apr_pool_t *p); - -#endif /* APACHE_SERVER_STATS_H */ - diff --git a/server/mpm/mpmt_pthread/scoreboard.h b/include/scoreboard.h similarity index 97% rename from server/mpm/mpmt_pthread/scoreboard.h rename to include/scoreboard.h index 80388a9eea..affca95451 100644 --- a/server/mpm/mpmt_pthread/scoreboard.h +++ b/include/scoreboard.h @@ -58,7 +58,6 @@ #ifndef APACHE_SCOREBOARD_H #define APACHE_SCOREBOARD_H -#include #ifdef __cplusplus extern "C" { #endif @@ -139,13 +138,13 @@ typedef unsigned vtime_t; */ typedef int ap_generation_t; -/* stuff which is thread specific */ +/* stuff which is thread/process specific */ typedef struct { #ifdef OPTIMIZE_TIMEOUTS vtime_t cur_vtime; /* the child's current vtime */ unsigned short timeout_len; /* length of the timeout */ #endif - pthread_t tid; + int thread_num; unsigned char status; unsigned long access_count; unsigned long bytes_served; @@ -165,7 +164,7 @@ typedef struct { char request[64]; /* We just want an idea... */ server_rec *vhostrec; /* What virtual host is being accessed? */ /* SEE ABOVE FOR SAFE USAGE! */ -} thread_score; +} short_score; typedef struct { ap_generation_t running_generation; /* the generation of children which @@ -184,7 +183,7 @@ typedef struct { } parent_score; typedef struct { - thread_score servers[HARD_SERVER_LIMIT][HARD_THREAD_LIMIT]; + short_score servers[HARD_SERVER_LIMIT][HARD_THREAD_LIMIT]; parent_score parent[HARD_SERVER_LIMIT]; global_score global; } scoreboard; @@ -214,7 +213,6 @@ AP_DECLARE(int) ap_exists_scoreboard_image(void); void reinit_scoreboard(apr_pool_t *p); apr_status_t ap_cleanup_shared_mem(void *d); AP_DECLARE(void) ap_sync_scoreboard_image(void); -void ap_mpmt_pthread_force_reset_connection_status(long conn_id); AP_DECLARE(void) reopen_scoreboard(apr_pool_t *p); @@ -228,6 +226,8 @@ void ap_time_process_request(int child_num, int thread_num, int status); AP_DECLARE_DATA extern scoreboard *ap_scoreboard_image; AP_DECLARE_DATA extern const char *ap_scoreboard_fname; +AP_DECLARE_DATA extern int ap_extended_status; +AP_DECLARE_DATA apr_time_t ap_restart_time; AP_DECLARE_DATA extern ap_generation_t volatile ap_my_generation; diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c index edf45bd74e..a01af0dbcd 100644 --- a/modules/generators/mod_status.c +++ b/modules/generators/mod_status.c @@ -56,11 +56,74 @@ * University of Illinois, Urbana-Champaign. */ +/* Status Module. Display lots of internal data about how Apache is + * performing and the state of all children processes. + * + * To enable this, add the following lines into any config file: + * + * + * SetHandler server-status + * + * + * You may want to protect this location by password or domain so no one + * else can look at it. Then you can access the statistics with a URL like: + * + * http://your_server_name/server-status + * + * /server-status - Returns page using tables + * /server-status?notable - Returns page for browsers without table support + * /server-status?refresh - Returns page with 1 second refresh + * /server-status?refresh=6 - Returns page with refresh every 6 seconds + * /server-status?auto - Returns page with data for automatic parsing + * + * Mark Cox, mark@ukweb.com, November 1995 + * + * 12.11.95 Initial version for www.telescope.org + * 13.3.96 Updated to remove rprintf's [Mark] + * 18.3.96 Added CPU usage, process information, and tidied [Ben Laurie] + * 18.3.96 Make extra Scoreboard variables #definable + * 25.3.96 Make short report have full precision [Ben Laurie suggested] + * 25.3.96 Show uptime better [Mark/Ben Laurie] + * 29.3.96 Better HTML and explanation [Mark/Rob Hartill suggested] + * 09.4.96 Added message for non-STATUS compiled version + * 18.4.96 Added per child and per slot counters [Jim Jagielski] + * 01.5.96 Table format, cleanup, even more spiffy data [Chuck Murcko/Jim J.] + * 18.5.96 Adapted to use new rprintf() routine, incidentally fixing a missing + * piece in short reports [Ben Laurie] + * 21.5.96 Additional Status codes (DNS and LOGGING only enabled if + * extended STATUS is enabled) [George Burgyan/Jim J.] + * 10.8.98 Allow for extended status info at runtime (no more STATUS) + * [Jim J.] + */ + +#define CORE_PRIVATE #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_protocol.h" -#include "mpm_status.h" +#include "http_main.h" +#include "util_script.h" +#include +#include "scoreboard.h" +#include "http_log.h" + +#ifdef NEXT +#if (NX_CURRENT_COMPILER_RELEASE == 410) +#ifdef m68k +#define HZ 64 +#else +#define HZ 100 +#endif +#else +#include +#endif +#endif /* NEXT */ + +#define STATUS_MAXLINE 64 + +#define KBYTE 1024 +#define MBYTE 1048576L +#define GBYTE 1073741824L #ifndef DEFAULT_TIME_FORMAT #define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z" @@ -70,76 +133,647 @@ module AP_MODULE_DECLARE_DATA status_module; -static int print_status_value(void *data, const char *key, const char *val) +/* + *command-related code. This is here to prevent use of ExtendedStatus + * without status_module included. + */ +static const char *set_extended_status(cmd_parms *cmd, void *dummy, int arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + ap_extended_status = arg; + return NULL; +} + +static const command_rec status_module_cmds[] = { - request_rec *r = (request_rec *) data; + AP_INIT_FLAG("ExtendedStatus", set_extended_status, NULL, RSRC_CONF, + "\"On\" to enable extended status information, \"Off\" to disable"), + {NULL} +}; + +/* Format the number of bytes nicely */ +static void format_byte_out(request_rec *r, unsigned long bytes) +{ + if (bytes < (5 * KBYTE)) + ap_rprintf(r, "%d B", (int) bytes); + else if (bytes < (MBYTE / 2)) + ap_rprintf(r, "%.1f kB", (float) bytes / KBYTE); + else if (bytes < (GBYTE / 2)) + ap_rprintf(r, "%.1f MB", (float) bytes / MBYTE); + else + ap_rprintf(r, "%.1f GB", (float) bytes / GBYTE); +} - ap_rprintf(r, "
%s\n
%s\n", key, val); - return 1; +static void format_kbyte_out(request_rec *r, unsigned long kbytes) +{ + if (kbytes < KBYTE) + ap_rprintf(r, "%d kB", (int) kbytes); + else if (kbytes < MBYTE) + ap_rprintf(r, "%.1f MB", (float) kbytes / KBYTE); + else + ap_rprintf(r, "%.1f GB", (float) kbytes / MBYTE); } +static void show_time(request_rec *r, time_t tsecs) +{ + long days, hrs, mins, secs; + + secs = tsecs % 60; + tsecs /= 60; + mins = tsecs % 60; + tsecs /= 60; + hrs = tsecs % 24; + days = tsecs / 24; + if (days) + ap_rprintf(r, " %ld day%s", days, days == 1 ? "" : "s"); + if (hrs) + ap_rprintf(r, " %ld hour%s", hrs, hrs == 1 ? "" : "s"); + if (mins) + ap_rprintf(r, " %ld minute%s", mins, mins == 1 ? "" : "s"); + if (secs) + ap_rprintf(r, " %ld second%s", secs, secs == 1 ? "" : "s"); +} + +/* Main handler for x-httpd-status requests */ + +/* 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 + +struct stat_opt { + int id; + const char *form_data_str; + const char *hdr_out_str; +}; + +static const struct stat_opt status_options[] = /* see #defines above */ +{ + {STAT_OPT_REFRESH, "refresh", "Refresh"}, + {STAT_OPT_NOTABLE, "notable", NULL}, + {STAT_OPT_AUTO, "auto", NULL}, + {STAT_OPT_END, NULL, NULL} +}; + +static char status_flags[SERVER_NUM_STATUS]; + static int status_handler(request_rec *r) { - int i; - apr_array_header_t *server_status; - ap_status_table_row_t *status_rows; + const char *loc; + time_t nowtime = time(NULL); + time_t up_time; + int j, i, res; + int ready = 0; + int busy = 0; + unsigned long count = 0; + unsigned long lres, bytes; + unsigned long my_lres, my_bytes, conn_bytes; + unsigned short conn_lres; + unsigned long bcount = 0; + unsigned long kbcount = 0; + long req_time; +#ifndef NO_TIMES +#ifdef _SC_CLK_TCK + float tick = sysconf(_SC_CLK_TCK); +#else + float tick = HZ; +#endif +#endif + int short_report = 0; + int no_table_report = 0; + short_score score_record; + parent_score ps_record; + char stat_buffer[HARD_SERVER_LIMIT * HARD_THREAD_LIMIT]; + int pid_buffer[HARD_SERVER_LIMIT * HARD_THREAD_LIMIT]; + clock_t tu, ts, tcu, tcs; + server_rec *vhost; if (strcmp(r->handler, STATUS_MAGIC_TYPE) && strcmp(r->handler, "server-status")) { return DECLINED; } + tu = ts = tcu = tcs = 0; + + if (!ap_exists_scoreboard_image()) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, + "Server status unavailable in inetd mode"); + return HTTP_INTERNAL_SERVER_ERROR; + } r->allowed = (1 << M_GET); if (r->method_number != M_GET) return DECLINED; r->content_type = "text/html"; + /* + * Simple table-driven form data set parser that lets you alter the header + */ + + if (r->args) { + i = 0; + while (status_options[i].id != STAT_OPT_END) { + if ((loc = ap_strstr_c(r->args, status_options[i].form_data_str)) != NULL) { + switch (status_options[i].id) { + case STAT_OPT_REFRESH: + if (*(loc + strlen(status_options[i].form_data_str)) == '=' + && atol(loc + strlen(status_options[i].form_data_str) + + 1) > 0) + apr_table_set(r->headers_out, + status_options[i].hdr_out_str, + loc + strlen(status_options[i].hdr_out_str) + 1); + else + apr_table_set(r->headers_out, + status_options[i].hdr_out_str, "1"); + break; + case STAT_OPT_NOTABLE: + no_table_report = 1; + break; + case STAT_OPT_AUTO: + r->content_type = "text/plain"; + short_report = 1; + break; + } + } + i++; + } + } + ap_send_http_header(r); if (r->header_only) return 0; - server_status = ap_get_status_table(r->pool); - - ap_rputs(DOCTYPE_HTML_3_2 - "\nApache Status\n\n", - r); - ap_rputs("

Apache Server Status for ", r); - ap_rvputs(r, ap_get_server_name(r), "

\n\n", NULL); - ap_rvputs(r, "Server Version: ", - ap_get_server_version(), "
\n", NULL); - ap_rvputs(r, "Server Built: ", - ap_get_server_built(), "
\n
\n", NULL); - ap_rvputs(r, "Current Time: ", - ap_ht_time(r->pool, apr_now(), DEFAULT_TIME_FORMAT, 0), "
\n", NULL); - - if (server_status) { - ap_rprintf(r, "\n%d connections currently being processed\n", - server_status->nelts); - - status_rows = (ap_status_table_row_t *) server_status->elts; - for (i = 0; i < server_status->nelts; i++) { - ap_rprintf(r, "

Connection %ld

\n", status_rows[i].conn_id); - apr_table_do(print_status_value, (void *) r, status_rows[i].data, - NULL); + ap_sync_scoreboard_image(); + for (i = 0; i < HARD_SERVER_LIMIT; ++i) { + for (j = 0; j < HARD_THREAD_LIMIT; ++j) { + int indx = (i * HARD_THREAD_LIMIT) + j; + + score_record = ap_scoreboard_image->servers[i][j]; + ps_record = ap_scoreboard_image->parent[i]; + res = score_record.status; + stat_buffer[indx] = status_flags[res]; + pid_buffer[indx] = (int) ps_record.pid; + if (res == SERVER_READY) + ready++; + else if (res != SERVER_DEAD) + busy++; + if (ap_extended_status) { + lres = score_record.access_count; + bytes = score_record.bytes_served; + if (lres != 0 || (res != SERVER_READY && res != SERVER_DEAD)) { +#ifndef NO_TIMES + tu += score_record.times.tms_utime; + ts += score_record.times.tms_stime; + tcu += score_record.times.tms_cutime; + tcs += score_record.times.tms_cstime; +#endif /* NO_TIMES */ + count += lres; + bcount += bytes; + if (bcount >= KBYTE) { + kbcount += (bcount >> 10); + bcount = bcount & 0x3ff; + } + } + } + } + } + + up_time = nowtime - ap_restart_time; + + if (!short_report) { + ap_rputs(DOCTYPE_HTML_3_2 + "\nApache Status\n\n", + r); + ap_rputs("

Apache Server Status for ", r); + ap_rvputs(r, ap_get_server_name(r), "

\n\n", NULL); + ap_rvputs(r, "Server Version: ", + ap_get_server_version(), "
\n", NULL); + ap_rvputs(r, "Server Built: ", + ap_get_server_built(), "
\n
\n", NULL); + ap_rvputs(r, "Current Time: ", + ap_ht_time(r->pool, nowtime, DEFAULT_TIME_FORMAT, 0), "
\n", NULL); + ap_rvputs(r, "Restart Time: ", + ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0), + "
\n", NULL); + ap_rprintf(r, "Parent Server Generation: %d
\n", (int) ap_my_generation); + ap_rputs("Server uptime: ", r); + show_time(r, up_time); + ap_rputs("
\n", r); + } + + if (ap_extended_status) { + if (short_report) { + ap_rprintf(r, "Total Accesses: %lu\nTotal kBytes: %lu\n", + count, kbcount); + +#ifndef NO_TIMES + /* Allow for OS/2 not having CPU stats */ + if (ts || tu || tcu || tcs) + ap_rprintf(r, "CPULoad: %g\n", + (tu + ts + tcu + tcs) / tick / up_time * 100.); +#endif + + ap_rprintf(r, "Uptime: %ld\n", (long) (up_time)); + if (up_time > 0) + ap_rprintf(r, "ReqPerSec: %g\n", + (float) count / (float) up_time); + + if (up_time > 0) + ap_rprintf(r, "BytesPerSec: %g\n", + KBYTE * (float) kbcount / (float) up_time); + + if (count > 0) + ap_rprintf(r, "BytesPerReq: %g\n", + KBYTE * (float) kbcount / (float) count); + } + else { /* !short_report */ + ap_rprintf(r, "Total accesses: %lu - Total Traffic: ", count); + format_kbyte_out(r, kbcount); + +#ifndef NO_TIMES + /* Allow for OS/2 not having CPU stats */ + ap_rputs("
\n", r); + ap_rprintf(r, "CPU Usage: u%g s%g cu%g cs%g", + tu / tick, ts / tick, tcu / tick, tcs / tick); + + if (ts || tu || tcu || tcs) + ap_rprintf(r, " - %.3g%% CPU load", + (tu + ts + tcu + tcs) / tick / up_time * 100.); +#endif + + ap_rputs("
\n", r); + + if (up_time > 0) + ap_rprintf(r, "%.3g requests/sec - ", + (float) count / (float) up_time); + + if (up_time > 0) { + format_byte_out(r, KBYTE * (float) kbcount / (float) up_time); + ap_rputs("/second - ", r); + } + + if (count > 0) { + format_byte_out(r, KBYTE * (float) kbcount / (float) count); + ap_rputs("/request", r); + } + + ap_rputs("
\n", r); + } /* short_report */ + } /* ap_extended_status */ + + if (!short_report) + ap_rprintf(r, "\n%d requests currently being processed, %d idle servers\n" + ,busy, ready); + else + ap_rprintf(r, "BusyServers: %d\nIdleServers: %d\n", busy, ready); + + /* send the scoreboard 'table' out */ + + if (!short_report) + ap_rputs("
", r);
+    else
+	ap_rputs("Scoreboard: ", r);
+
+    for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
+        for (j = 0; j < HARD_THREAD_LIMIT; ++j) {
+            int indx = (i * HARD_THREAD_LIMIT) + j;
+	    ap_rputc(stat_buffer[indx], r);
+	    if ((indx % STATUS_MAXLINE == (STATUS_MAXLINE - 1)) && !short_report)
+	        ap_rputs("\n", r);
         }
     }
-    ap_rputs("\n", r);
+
+    if (short_report)
+	ap_rputs("\n", r);
+    else {
+	ap_rputs("
\n", r); + ap_rputs("Scoreboard Key:
\n", r); + ap_rputs("\"_\" Waiting for Connection, \n", r); + ap_rputs("\"S\" Starting up, \n", r); + ap_rputs("\"R\" Reading Request,
\n", r); + ap_rputs("\"W\" Sending Reply, \n", r); + ap_rputs("\"K\" Keepalive (read), \n", r); + ap_rputs("\"D\" DNS Lookup,
\n", r); + ap_rputs("\"L\" Logging, \n", r); + ap_rputs("\"G\" Gracefully finishing, \n", r); + ap_rputs("\".\" Open slot with no current process

\n", r); + ap_rputs("

\n", r); + if (!ap_extended_status) { + int j = 0; + int k; + ap_rputs("PID Key:
\n", r); + ap_rputs("

\n", r);
+	    for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
+                for (k = 0; k < HARD_THREAD_LIMIT; ++k) {
+                    int indx = (i * HARD_THREAD_LIMIT) + j;
+
+		    if (stat_buffer[indx] != '.') {
+		        ap_rprintf(r, "   %d in state: %c ", pid_buffer[i],
+		        stat_buffer[indx]);
+		        if (++j >= 3) {
+		    	    ap_rputs("\n", r);
+			    j = 0;
+		        } else
+		    	    ap_rputs(",", r);
+		    }
+                }
+	    }
+	    ap_rputs("\n", r);
+	    ap_rputs("
\n", r); + } + } + + if (ap_extended_status) { + if (!short_report) { + if (no_table_report) + ap_rputs("


Server Details

\n\n", r); + else +#ifdef NO_TIMES + /* Allow for OS/2 not having CPU stats */ + ap_rputs("

\n\n\n\n", r); +#else + ap_rputs("

\n\n

SrvPIDAccM\nSSReqConnChildSlotClientVHostRequest
\n\n", r); +#endif + } + + for (i = 0; i < HARD_SERVER_LIMIT; ++i) { + for (j = 0; j < HARD_THREAD_LIMIT; ++j) { + score_record = ap_scoreboard_image->servers[i][j]; + ps_record = ap_scoreboard_image->parent[i]; + vhost = score_record.vhostrec; + if (ps_record.generation != ap_my_generation) { + vhost = NULL; + } + +#if defined(NO_GETTIMEOFDAY) +#ifndef NO_TIMES + if (score_record.start_time == (clock_t) 0) +#endif /* NO_TIMES */ + req_time = 0L; +#ifndef NO_TIMES + else { + req_time = score_record.stop_time - score_record.start_time; + req_time = (req_time * 1000) / (int) tick; + } +#endif /* NO_TIMES */ +#else + if (score_record.start_time == 0L && + score_record.start_time == 0L) + req_time = 0L; + else + req_time = + ((score_record.stop_time - score_record.start_time) * 1000) + + ((score_record.stop_time - score_record.start_time) / 1000); +#endif + if (req_time < 0L) + req_time = 0L; + + lres = score_record.access_count; + my_lres = score_record.my_access_count; + conn_lres = score_record.conn_count; + bytes = score_record.bytes_served; + my_bytes = score_record.my_bytes_served; + conn_bytes = score_record.conn_bytes; + if (lres != 0 || (score_record.status != SERVER_READY + && score_record.status != SERVER_DEAD)) { + if (!short_report) { + if (no_table_report) { + if (score_record.status == SERVER_DEAD) + ap_rprintf(r, + "Server %d-%d (-): %d|%lu|%lu [", + i, (int) ps_record.generation, (int) conn_lres, + my_lres, lres); + else + ap_rprintf(r, + "Server %d-%d (%d): %d|%lu|%lu [", + i, (int) ps_record.generation, + (int) ps_record.pid, + (int) conn_lres, my_lres, lres); + + switch (score_record.status) { + case SERVER_READY: + ap_rputs("Ready", r); + break; + case SERVER_STARTING: + ap_rputs("Starting", r); + break; + case SERVER_BUSY_READ: + ap_rputs("Read", r); + break; + case SERVER_BUSY_WRITE: + ap_rputs("Write", r); + break; + case SERVER_BUSY_KEEPALIVE: + ap_rputs("Keepalive", r); + break; + case SERVER_BUSY_LOG: + ap_rputs("Logging", r); + break; + case SERVER_BUSY_DNS: + ap_rputs("DNS lookup", r); + break; + case SERVER_DEAD: + ap_rputs("Dead", r); + break; + case SERVER_GRACEFUL: + ap_rputs("Graceful", r); + break; + default: + ap_rputs("?STATE?", r); + break; + } +#ifdef NO_TIMES + /* Allow for OS/2 not having CPU stats */ + ap_rprintf(r, "]\n %.0f %ld (", +#else + + ap_rprintf(r, "] u%g s%g cu%g cs%g\n %.0f %ld (", + score_record.times.tms_utime / tick, + score_record.times.tms_stime / tick, + score_record.times.tms_cutime / tick, + score_record.times.tms_cstime / tick, +#endif +#ifdef OPTIMIZE_TIMEOUTS + difftime(nowtime, ps_record.last_rtime), +#else + difftime(nowtime, score_record.last_used), +#endif + (long) req_time); + format_byte_out(r, conn_bytes); + ap_rputs("|", r); + format_byte_out(r, my_bytes); + ap_rputs("|", r); + format_byte_out(r, bytes); + ap_rputs(")\n", r); + ap_rprintf(r, " %s {%s}[%s]
\n\n", + ap_escape_html(r->pool, score_record.client), + ap_escape_html(r->pool, score_record.request), + vhost ? ap_escape_html(r->pool, + vhost->server_hostname) : "(unavailable)"); + } + else { /* !no_table_report */ + if (score_record.status == SERVER_DEAD) + ap_rprintf(r, + "\n\n"); + else + ap_rprintf(r, + "\n\n", + ap_escape_html(r->pool, score_record.client), + vhost ? ap_escape_html(r->pool, + vhost->server_hostname) : "(unavailable)", + ap_escape_html(r->pool, score_record.request)); + } /* no_table_report */ + } /* !short_report */ + } /* if () */ + } /* for () */ + } + + if (!(short_report || no_table_report)) { +#ifdef NO_TIMES + ap_rputs("
SrvPIDAccMCPU\nSSReqConnChildSlotClientVHostRequest
%d-%d-%d/%lu/%lu", + i, (int) ps_record.generation, + (int) conn_lres, my_lres, lres); + else + ap_rprintf(r, + "
%d-%d%d%d/%lu/%lu", + i, (int) ps_record.generation, + (int) ps_record.pid, (int) conn_lres, + my_lres, lres); + + switch (score_record.status) { + case SERVER_READY: + ap_rputs("_", r); + break; + case SERVER_STARTING: + ap_rputs("S", r); + break; + case SERVER_BUSY_READ: + ap_rputs("R", r); + break; + case SERVER_BUSY_WRITE: + ap_rputs("W", r); + break; + case SERVER_BUSY_KEEPALIVE: + ap_rputs("K", r); + break; + case SERVER_BUSY_LOG: + ap_rputs("L", r); + break; + case SERVER_BUSY_DNS: + ap_rputs("D", r); + break; + case SERVER_DEAD: + ap_rputs(".", r); + break; + case SERVER_GRACEFUL: + ap_rputs("G", r); + break; + default: + ap_rputs("?", r); + break; + } +#ifdef NO_TIMES + /* Allow for OS/2 not having CPU stats */ + ap_rprintf(r, "\n%.0f%ld", +#else + ap_rprintf(r, "\n%.2f%.0f%ld", + (score_record.times.tms_utime + + score_record.times.tms_stime + + score_record.times.tms_cutime + + score_record.times.tms_cstime) / tick, +#endif +#ifdef OPTIMIZE_TIMEOUTS + difftime(nowtime, ps_record.last_rtime), +#else + difftime(nowtime, score_record.last_used), +#endif + (long) req_time); + ap_rprintf(r, "%-1.1f%-2.2f%-2.2f\n", + (float) conn_bytes / KBYTE, (float) my_bytes / MBYTE, + (float) bytes / MBYTE); + if (score_record.status == SERVER_BUSY_READ) + ap_rprintf(r, + "??..reading..
%s%s%s
\n \ +


\ +\n \ +
SrvChild Server number - generation\n \ +
PIDOS process ID\n \ +
AccNumber of accesses this connection / this child / this slot\n \ +
MMode of operation\n \ +
SSSeconds since beginning of most recent request\n \ +
ReqMilliseconds required to process most recent request\n \ +
ConnKilobytes transferred this connection\n \ +
ChildMegabytes transferred this child\n \ +
SlotTotal megabytes transferred this slot\n \ +
\n", r); +#else + ap_rputs("\n \ +
\ +\n \ +
SrvChild Server number - generation\n \ +
PIDOS process ID\n \ +
AccNumber of accesses this connection / this child / this slot\n \ +
MMode of operation\n \ +
CPUCPU usage, number of seconds\n \ +
SSSeconds since beginning of most recent request\n \ +
ReqMilliseconds required to process most recent request\n \ +
ConnKilobytes transferred this connection\n \ +
ChildMegabytes transferred this child\n \ +
SlotTotal megabytes transferred this slot\n \ +
\n", r); +#endif + } + + } else { + + if (!short_report) { + ap_rputs("
To obtain a full report with current status information ", r); + ap_rputs("you need to use the ExtendedStatus On directive. \n", r); + } + + } + + if (!short_report) { + ap_rputs(ap_psignature("
\n",r), r); + ap_rputs("\n", r); + } + return 0; } + +static void status_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ + status_flags[SERVER_DEAD] = '.'; /* We don't want to assume these are in */ + status_flags[SERVER_READY] = '_'; /* any particular order in scoreboard.h */ + status_flags[SERVER_STARTING] = 'S'; + status_flags[SERVER_BUSY_READ] = 'R'; + status_flags[SERVER_BUSY_WRITE] = 'W'; + status_flags[SERVER_BUSY_KEEPALIVE] = 'K'; + status_flags[SERVER_BUSY_LOG] = 'L'; + status_flags[SERVER_BUSY_DNS] = 'D'; + status_flags[SERVER_GRACEFUL] = 'G'; +} + static void register_hooks(apr_pool_t *p) { ap_hook_handler(status_handler, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(status_init, NULL, NULL, APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA status_module = { STANDARD20_MODULE_STUFF, - NULL, /* create per-dir config */ - NULL, /* merge per-dir config */ + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ - NULL, /* command table */ - register_hooks /* register hooks */ + status_module_cmds, /* command table */ + register_hooks /* register_hooks */ }; + diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 659c8b7531..5206e67ddc 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -91,7 +91,6 @@ #include "util_date.h" /* For parseHTTPdate and BAD_DATE */ #include "util_charset.h" #include "util_ebcdic.h" -#include "mpm_status.h" #include "mod_core.h" @@ -1211,7 +1210,9 @@ static int read_request_line(request_rec *r) char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */ const char *ll = l; const char *uri; +#if 0 conn_rec *conn = r->connection; +#endif int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */ int len; @@ -1277,7 +1278,12 @@ static int read_request_line(request_rec *r) r->request_time = apr_now(); r->the_request = apr_pstrdup(r->pool, l); r->method = ap_getword_white(r->pool, &ll); - ap_update_connection_status(conn->id, "Method", r->method); +#if 0 +/* XXX If we want to keep track of the Method, the protocol module should do + * it. That support isn't in the scoreboard yet. Hopefully next week + * sometime. rbb */ + ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method", r->method); +#endif uri = ap_getword_white(r->pool, &ll); /* Provide quick information about the request method as soon as known */ @@ -1302,7 +1308,11 @@ static int read_request_line(request_rec *r) r->assbackwards = (ll[0] == '\0'); r->protocol = apr_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9"); - ap_update_connection_status(conn->id, "Protocol", r->protocol); +/* XXX If we want to keep track of the Method, the protocol module should do + * it. That support isn't in the scoreboard yet. Hopefully next week + * sometime. rbb + ap_update_connection_status(conn->id, "Protocol", r->protocol); + */ if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor) && minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */ diff --git a/server/Makefile.in b/server/Makefile.in index 02cf73d917..1e3943ff58 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -12,7 +12,7 @@ LTLIBRARY_SOURCES = \ util_script.c util_uri.c util_md5.c util_cfgtree.c util_ebcdic.c \ rfc1413.c connection.c listen.c \ mpm_common.c util_charset.c util_debug.c util_xml.c \ - util_filter.c exports.c buildmark.c + util_filter.c exports.c buildmark.c scoreboard.c targets = delete-exports $(LTLIBRARY_NAME) diff --git a/server/config.m4 b/server/config.m4 index 0c48f54c17..479fbeafff 100644 --- a/server/config.m4 +++ b/server/config.m4 @@ -49,3 +49,7 @@ dnl ## Check for library functions AC_CHECK_FUNCS( syslog \ ) + +dnl Obsolete scoreboard code uses this. + AC_CHECK_HEADERS(sys/times.h) + AC_CHECK_FUNCS(times) diff --git a/server/connection.c b/server/connection.c index 6287fa2177..bd1ae533ee 100644 --- a/server/connection.c +++ b/server/connection.c @@ -64,9 +64,10 @@ #include "http_request.h" #include "http_protocol.h" #include "ap_mpm.h" -#include "mpm_status.h" +#include "mpm_default.h" #include "http_config.h" #include "http_vhost.h" +#include "scoreboard.h" #include "http_log.h" #include "util_filter.h" @@ -240,26 +241,26 @@ AP_CORE_DECLARE_NONSTD(int) ap_process_http_connection(conn_rec *c) * until no requests are left or we decide to close. */ - ap_update_connection_status(c->id, "Status", "Reading"); + ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_READ, NULL); while ((r = ap_read_request(c)) != NULL) { /* process the request if it was read without error */ - ap_update_connection_status(c->id, "Status", "Writing"); + ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_WRITE, NULL); if (r->status == HTTP_OK) ap_process_request(r); if (!c->keepalive || c->aborted) break; - ap_update_connection_status(c->id, "Status", "Keepalive"); + ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_KEEPALIVE, NULL); apr_destroy_pool(r->pool); if (ap_graceful_stop_signalled()) break; } - ap_reset_connection_status(c->id); + ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_READY, NULL); return OK; } diff --git a/server/mpm/beos/Makefile.in b/server/mpm/beos/Makefile.in index ba75075533..3f88b0415f 100644 --- a/server/mpm/beos/Makefile.in +++ b/server/mpm/beos/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libbeos.la -LTLIBRARY_SOURCES = beos.c scoreboard.c +LTLIBRARY_SOURCES = beos.c include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/beos/scoreboard.c b/server/mpm/beos/scoreboard.c deleted file mode 100644 index e11eb0dd84..0000000000 --- a/server/mpm/beos/scoreboard.c +++ /dev/null @@ -1,227 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * 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 "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_config.h" -#include "mpm_status.h" -#include "mpm.h" /* includes scoreboard.h */ -#include "beosd.h" -#include "http_conf_globals.h" -#include "beos.h" - -scoreboard *ap_scoreboard_image = NULL; -extern apr_pool_t * pconf; -static int maintain_connection_status = 1; - -void reinit_scoreboard(apr_pool_t *p) -{ - if (!ap_scoreboard_image) - ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE); - if (ap_scoreboard_image == NULL) { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Ouch! Out of memory reiniting scoreboard!"); - } - memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); -} - -void cleanup_scoreboard(void) -{ - ap_assert(ap_scoreboard_image); - free(ap_scoreboard_image); - ap_scoreboard_image = NULL; -} - -AP_DECLARE(int) ap_exists_scoreboard_image(void) -{ - return (ap_scoreboard_image ? 1 : 0); -} - - -void ap_update_connection_status(long conn_id, const char *key, - const char *value) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; - } - i++; - } - if (i >= STATUSES_PER_CONNECTION) { - return; - } - apr_cpystrn(ss->key, key, KEY_LENGTH); - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; -} - -void ap_reset_connection_status(long conn_id) -{ - if (maintain_connection_status) { - ap_beos_force_reset_connection_status(conn_id); - } -} - -void ap_beos_set_maintain_connection_status(int flag) { - maintain_connection_status = flag; - return; -} - -void ap_beos_force_reset_connection_status(long conn_id) -{ - int i; - - for (i = 0; i < STATUSES_PER_CONNECTION; i++) { - ap_scoreboard_image->table[conn_id][i].key[0] = '\0'; - } -} - -const char *ap_get_connection_status(long conn_id, const char *key) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return ""; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - return ss->value; - } - } - - return NULL; -} - -apr_array_header_t *ap_get_connections(apr_pool_t *p) -{ - int i; - apr_array_header_t *connection_list; - long *array_slot; - - connection_list = apr_make_array(p, 0, sizeof(long)); - for (i = 0; i < ap_max_child_assigned; i++) { - if (ap_scoreboard_image->table[i][0].key[0] != '\0') { - array_slot = apr_push_array(connection_list); - *array_slot = i; - } - } - return connection_list; -} - -apr_array_header_t *ap_get_connection_keys(apr_pool_t *p, long conn_id) -{ - int i = 0; - status_table_entry *ss; - apr_array_header_t *key_list; - char **array_slot; - - key_list = apr_make_array(p, 0, KEY_LENGTH * sizeof(char)); - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - array_slot = apr_push_array(key_list); - *array_slot = (char*)apr_pstrdup(p, ss->key); - i++; - } - return key_list; -} - -apr_array_header_t *ap_get_status_table(apr_pool_t *p) -{ - int i, j; - apr_array_header_t *server_status; - ap_status_table_row_t *array_slot; - status_table_entry *ss; - - server_status = apr_make_array(p, 0, sizeof(ap_status_table_row_t)); - - for (i = 0; i < ap_max_child_assigned; i++) { - if (ap_scoreboard_image->table[i][0].key[0] == '\0') - continue; - array_slot = apr_push_array(server_status); - array_slot->data = apr_make_table(p, 0); - array_slot->conn_id = i; - - for (j = 0; j < STATUSES_PER_CONNECTION; j++) { - ss = &(ap_scoreboard_image->table[i][j]); - if (ss->key[0] != '\0') { - apr_table_add(array_slot->data, ss->key, ss->value); - } - else { - break; - } - } - } - return server_status; -} diff --git a/server/mpm/beos/scoreboard.h b/server/mpm/beos/scoreboard.h deleted file mode 100644 index a024c1795e..0000000000 --- a/server/mpm/beos/scoreboard.h +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef BEOS_SCOREBOARD_H -#define BEOS_SCOREBOARD_H -#ifdef __cplusplus -extern "C" { -#endif - - -#include -#include "mpm_default.h" /* For HARD_.*_LIMIT */ - -AP_DECLARE(int) ap_exists_scoreboard_image(void); -void reinit_scoareboard(apr_pool_t *p); -void cleanup_scoreboard(void); -void ap_beos_set_maintain_connection_status(int flag); -void ap_beos_force_reset_connection_status(long conn_id); -void reinit_scoreboard(apr_pool_t *p); -void update_scoreboard_global(void); -AP_DECLARE(int) find_child_by_pid(int pid); -int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r); -void ap_time_process_request(int child_num, int thread_num, int status); - -/* Add support for connection table functions */ - -#define KEY_LENGTH 16 -#define VALUE_LENGTH 64 - -typedef struct { - char key[KEY_LENGTH]; - char value[VALUE_LENGTH]; -} status_table_entry; - -#define STATUSES_PER_CONNECTION 10 - -typedef struct { - status_table_entry - table[HARD_THREAD_LIMIT][STATUSES_PER_CONNECTION]; -} scoreboard; - -#define SCOREBOARD_SIZE sizeof(scoreboard) - -#ifdef __cplusplus -} -#endif - -#endif /* !BEOS_SCOREBOARD_H */ diff --git a/server/mpm/dexter/Makefile.in b/server/mpm/dexter/Makefile.in index 05c5fa702b..8ac3d71dfc 100644 --- a/server/mpm/dexter/Makefile.in +++ b/server/mpm/dexter/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libdexter.la -LTLIBRARY_SOURCES = dexter.c scoreboard.c +LTLIBRARY_SOURCES = dexter.c include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/dexter/dexter.c b/server/mpm/dexter/dexter.c index 9b13a85e2f..7f198e9751 100644 --- a/server/mpm/dexter/dexter.c +++ b/server/mpm/dexter/dexter.c @@ -99,7 +99,6 @@ static int max_spare_threads = 0; static int max_threads = 0; static int max_requests_per_child = 0; static const char *ap_pid_fname=NULL; -AP_DECLARE_DATA const char *ap_scoreboard_fname=NULL; static int num_daemons=0; static int workers_may_exit = 0; static int requests_this_child; @@ -117,6 +116,7 @@ struct ap_ctable ap_child_table[HARD_SERVER_LIMIT]; * many child processes in this MPM. */ int ap_max_daemons_limit = -1; +int ap_threads_per_child = HARD_THREAD_LIMIT; char ap_coredump_dir[MAX_STRING_LEN]; @@ -214,6 +214,7 @@ static void just_die(int sig) static int volatile shutdown_pending; static int volatile restart_pending; static int volatile is_graceful; +ap_generation_t volatile ap_my_generation=0; /* * ap_start_shutdown() and ap_start_restart(), below, are a first stab at @@ -414,6 +415,9 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id) ap_sock_disable_nagle(sock); + (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(conn_id), + SERVER_BUSY_READ, (request_rec *) NULL); + current_conn = ap_new_connection(p, ap_server_conf, sock, conn_id); ap_process_connection(current_conn); @@ -510,6 +514,10 @@ static void *worker_thread(void *arg) pthread_mutex_unlock(&thread_pool_parent_mutex); apr_create_pool(&ptrans, tpool); + (void) ap_update_child_status(child_num, thread_num, SERVER_STARTING, + (request_rec *) NULL); + + apr_setup_poll(&pollset, num_listenfds+1, tpool); for(n=0 ; n <= num_listenfds ; ++n) apr_add_poll_socket(pollset, listenfds[n], APR_POLLIN); @@ -531,6 +539,10 @@ static void *worker_thread(void *arg) else { thread_just_started = 0; } + + (void) ap_update_child_status(child_num, thread_num, SERVER_READY, + (request_rec *) NULL); + if ((rv = SAFE_ACCEPT(apr_lock(accept_mutex))) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, @@ -630,7 +642,8 @@ static void *worker_thread(void *arg) } pthread_mutex_lock(&thread_pool_parent_mutex); - apr_destroy_pool(tpool); + ap_update_child_status(child_num, thread_num, SERVER_DEAD, + (request_rec *) NULL); pthread_mutex_unlock(&thread_pool_parent_mutex); pthread_mutex_lock(&worker_thread_count_mutex); worker_thread_count--; @@ -768,9 +781,12 @@ static int make_child(server_rec *s, int slot, time_t now) child_main(slot); } + (void) ap_update_child_status(slot, 0, SERVER_STARTING, (request_rec *) NULL); + if ((pid = fork()) == -1) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process"); + (void) ap_update_child_status(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. */ @@ -902,17 +918,13 @@ static void server_main_loop(int remaining_children_to_start) child_slot = -1; for (i = 0; i < ap_max_daemons_limit; ++i) { if (ap_child_table[i].pid == pid.pid) { - int j; - child_slot = i; - for (j = 0; j < HARD_THREAD_LIMIT; j++) { - ap_dexter_force_reset_connection_status(i * HARD_THREAD_LIMIT + j); - } break; } } if (child_slot >= 0) { ap_child_table[child_slot].pid = 0; + ap_update_child_status(child_slot, i, SERVER_DEAD, (request_rec *) NULL); if (remaining_children_to_start && child_slot < num_daemons) { @@ -1152,7 +1164,6 @@ static void dexter_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp ap_scoreboard_fname = DEFAULT_SCOREBOARD; lock_fname = DEFAULT_LOCKFILE; max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; - ap_dexter_set_maintain_connection_status(1); apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); } @@ -1325,18 +1336,6 @@ static const char *set_max_requests(cmd_parms *cmd, void *dummy, const char *arg return NULL; } -static const char *set_maintain_connection_status(cmd_parms *cmd, - void *dummy, int arg) -{ - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); - if (err != NULL) { - return err; - } - - ap_dexter_set_maintain_connection_status(arg != 0); - return NULL; -} - static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, const char *arg) { apr_finfo_t finfo; @@ -1377,8 +1376,6 @@ AP_INIT_TAKE1("MaxThreadsPerChild", set_max_threads, NULL, RSRC_CONF, "Maximum number of threads per child"), AP_INIT_TAKE1("MaxRequestsPerChild", set_max_requests, NULL, RSRC_CONF, "Maximum number of requests a particular child serves before dying."), -AP_INIT_FLAG("ConnectionStatus", set_maintain_connection_status, NULL, RSRC_CONF, - "Whether or not to maintain status information on current connections"), AP_INIT_TAKE1("CoreDumpDirectory", set_coredumpdir, NULL, RSRC_CONF, "The location of the directory Apache changes to before dumping core"), { NULL } diff --git a/server/mpm/dexter/mpm.h b/server/mpm/dexter/mpm.h index cd7da3c058..7fc39b1bd8 100644 --- a/server/mpm/dexter/mpm.h +++ b/server/mpm/dexter/mpm.h @@ -80,6 +80,7 @@ typedef struct ap_ctable{ unsigned char status; } ap_ctable; +extern int ap_threads_per_child; extern int ap_max_daemons_limit; extern ap_ctable ap_child_table[HARD_SERVER_LIMIT]; extern server_rec *ap_server_conf; diff --git a/server/mpm/dexter/mpm_default.h b/server/mpm/dexter/mpm_default.h index 5bd323b09b..6a980e08a8 100644 --- a/server/mpm/dexter/mpm_default.h +++ b/server/mpm/dexter/mpm_default.h @@ -59,6 +59,9 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H +#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_SERVER_LIMIT) + HARD_THREAD_LIMIT) +#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_SERVER_LIMIT), (i % HARD_THREAD_LIMIT) + /* Number of threads to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ diff --git a/server/mpm/dexter/scoreboard.c b/server/mpm/dexter/scoreboard.c deleted file mode 100644 index e3cbd9b158..0000000000 --- a/server/mpm/dexter/scoreboard.c +++ /dev/null @@ -1,285 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * 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 "apr_strings.h" -#include "ap_config.h" -#include "httpd.h" -#include "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_config.h" -#include "unixd.h" -#include "http_conf_globals.h" -#include "mpm_status.h" -#include "scoreboard.h" -#include "mpm.h" /* for ap_max_daemons_limit */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -static scoreboard *ap_scoreboard_image = NULL; - -/***************************************************************** - * - * Dealing with the scoreboard... a lot of these variables are global - * only to avoid getting clobbered by the longjmp() that happens when - * a hard timeout expires... - * - * We begin with routines which deal with the file itself... - */ - -#if APR_HAS_SHARED_MEMORY -#include "apr_shmem.h" - -static apr_shmem_t *scoreboard_shm = NULL; - -apr_status_t ap_cleanup_shared_mem(void *d) -{ - apr_shm_free(scoreboard_shm, ap_scoreboard_image); - ap_scoreboard_image = NULL; - apr_shm_destroy(scoreboard_shm); - return APR_SUCCESS; -} - -static void setup_shared_mem(apr_pool_t *p) -{ - char buf[512]; - char errmsg[120]; - const char *fname; - apr_status_t rv; - - fname = ap_server_root_relative(p, ap_scoreboard_fname); - rv = apr_shm_init(&scoreboard_shm, SCOREBOARD_SIZE, fname, p); - if (rv != APR_SUCCESS) { - apr_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard: %s", - ap_server_argv0, apr_strerror(rv, errmsg, sizeof errmsg)); - fprintf(stderr, "%s\n", buf); - exit(APEXIT_INIT); - } - ap_scoreboard_image = apr_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE); - if (ap_scoreboard_image == NULL) { - apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard", - ap_server_argv0); - perror(buf); /* o.k. since MM sets errno */ - apr_shm_destroy(scoreboard_shm); - exit(APEXIT_INIT); - } - apr_register_cleanup(p, NULL, ap_cleanup_shared_mem, apr_null_cleanup); -} - -void reinit_scoreboard(apr_pool_t *p) -{ - if (ap_scoreboard_image == NULL) { - setup_shared_mem(p); - } - memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); -} -#endif /* APR_SHARED_MEM */ - -/**** - * Above code is shmem code. Below code is interacting with the shmem - ****/ - -static int maintain_connection_status = 1; - -void ap_dexter_set_maintain_connection_status(int flag) { - maintain_connection_status = flag; - return; -} - -/* Useful to erase the status of children that might be from previous - * generations */ -void ap_dexter_force_reset_connection_status(long conn_id) -{ - int i; - - for (i = 0; i < STATUSES_PER_CONNECTION; i++) { - ap_scoreboard_image->table[conn_id][i].key[0] = '\0'; - } -} - -void ap_reset_connection_status(long conn_id) -{ - if (maintain_connection_status) { - ap_dexter_force_reset_connection_status(conn_id); - } -} - -/* Don't mess with the string you get back from this function */ -const char *ap_get_connection_status(long conn_id, const char *key) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return ""; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - return ss->value; - } - } - - return NULL; -} - -apr_array_header_t *ap_get_connections(apr_pool_t *p) -{ - int i; - apr_array_header_t *connection_list; - long *array_slot; - - connection_list = apr_make_array(p, 0, sizeof(long)); - /* We assume that there is a connection iff it has an entry in the status - * table. Connections without any status sound problematic to me, so this - * is probably for the best. - manoj */ - for (i = 0; i < ap_max_daemons_limit*HARD_THREAD_LIMIT; i++) { - if (ap_scoreboard_image->table[i][0].key[0] != '\0') { - array_slot = apr_push_array(connection_list); - *array_slot = i; - } - } - return connection_list; -} - -apr_array_header_t *ap_get_connection_keys(apr_pool_t *p, long conn_id) -{ - int i = 0; - status_table_entry *ss; - apr_array_header_t *key_list; - char **array_slot; - - key_list = apr_make_array(p, 0, KEY_LENGTH * sizeof(char)); - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - array_slot = apr_push_array(key_list); - *array_slot = apr_pstrdup(p, ss->key); - i++; - } - return key_list; -} - -/* Note: no effort is made here to prevent multiple threads from messing with - * a single connection at the same time. ap_update_connection_status should - * only be called by the thread that owns the connection */ - -void ap_update_connection_status(long conn_id, const char *key, - const char *value) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; - } - i++; - } - /* Not found. Add an entry for this value */ - if (i >= STATUSES_PER_CONNECTION) { - /* No room. Oh well, not much anyone can do about it. */ - return; - } - apr_cpystrn(ss->key, key, KEY_LENGTH); - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; -} - -apr_array_header_t *ap_get_status_table(apr_pool_t *p) -{ - int i, j; - apr_array_header_t *server_status; - ap_status_table_row_t *array_slot; - status_table_entry *ss; - - server_status = apr_make_array(p, 0, sizeof(ap_status_table_row_t)); - - /* Go ahead and return what's in the connection status table even if we - * aren't maintaining it. We can at least look at what children from - * previous generations are up to. */ - - for (i = 0; i < ap_max_daemons_limit*HARD_THREAD_LIMIT; i++) { - if (ap_scoreboard_image->table[i][0].key[0] == '\0') - continue; - array_slot = apr_push_array(server_status); - array_slot->data = apr_make_table(p, 0); - array_slot->conn_id = i; - - for (j = 0; j < STATUSES_PER_CONNECTION; j++) { - ss = &(ap_scoreboard_image->table[i][j]); - if (ss->key[0] != '\0') { - apr_table_add(array_slot->data, ss->key, ss->value); - } - else { - break; - } - } - } - return server_status; -} diff --git a/server/mpm/dexter/scoreboard.h b/server/mpm/dexter/scoreboard.h deleted file mode 100644 index cda8b6ed90..0000000000 --- a/server/mpm/dexter/scoreboard.h +++ /dev/null @@ -1,109 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef APACHE_SCOREBOARD_H -#define APACHE_SCOREBOARD_H -#include -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef TPF -#include -#else -#include -#endif /* TPF */ - -#include "mpm_default.h" /* For HARD_.*_LIMIT */ - -/* The generic shared memory chunk code */ -void reinit_scoreboard(apr_pool_t *p); - -AP_DECLARE(void) reopen_scoreboard(apr_pool_t *p); - -/* The stuff for Dexter's status table */ - -#include "mpm_status.h" - -void ap_dexter_set_maintain_connection_status(int flag); -void ap_dexter_force_reset_connection_status(long conn_id); -#define KEY_LENGTH 16 -#define VALUE_LENGTH 64 -typedef struct { - char key[KEY_LENGTH]; - char value[VALUE_LENGTH]; -} status_table_entry; - -#define STATUSES_PER_CONNECTION 10 - -typedef struct { - status_table_entry - table[HARD_SERVER_LIMIT*HARD_THREAD_LIMIT][STATUSES_PER_CONNECTION]; -} scoreboard; - -#define SCOREBOARD_SIZE sizeof(scoreboard) - -AP_DECLARE_DATA extern const char *ap_scoreboard_fname; - -apr_status_t ap_cleanup_shared_mem(void *d); - -#ifdef __cplusplus -} -#endif - -#endif /* !APACHE_SCOREBOARD_H */ diff --git a/server/mpm/experimental/perchild/Makefile.in b/server/mpm/experimental/perchild/Makefile.in index 4d83d72d2d..374f130646 100644 --- a/server/mpm/experimental/perchild/Makefile.in +++ b/server/mpm/experimental/perchild/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libperchild.la -LTLIBRARY_SOURCES = perchild.c scoreboard.c +LTLIBRARY_SOURCES = perchild.c include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/mpmt_beos/Makefile.in b/server/mpm/mpmt_beos/Makefile.in index 13a7085cc2..fafd468610 100644 --- a/server/mpm/mpmt_beos/Makefile.in +++ b/server/mpm/mpmt_beos/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libmpmt_beos.la -LTLIBRARY_SOURCES = mpmt_beos.c scoreboard.c poll.c +LTLIBRARY_SOURCES = mpmt_beos.c poll.c include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/mpmt_beos/scoreboard.c b/server/mpm/mpmt_beos/scoreboard.c deleted file mode 100644 index f52bf27c08..0000000000 --- a/server/mpm/mpmt_beos/scoreboard.c +++ /dev/null @@ -1,228 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * 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 "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_config.h" -#include "mpm_status.h" -#include "beosd.h" -#include "http_conf_globals.h" -#include "mpmt_beos.h" -#include "mpm.h" /* includes scoreboard.h */ - -scoreboard *ap_scoreboard_image = NULL; -extern apr_pool_t * pconf; -extern int ap_max_daemons_limit; -static int maintain_connection_status = 1; - -void reinit_scoreboard(apr_pool_t *p) -{ - ap_assert(!ap_scoreboard_image); - ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE); - if (ap_scoreboard_image == NULL) { - ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL, - "Ouch! Out of memory reiniting scoreboard!"); - } - memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); -} - -void cleanup_scoreboard(void) -{ - ap_assert(ap_scoreboard_image); - free(ap_scoreboard_image); - ap_scoreboard_image = NULL; -} - -AP_DECLARE(int) ap_exists_scoreboard_image(void) -{ - return (ap_scoreboard_image ? 1 : 0); -} - - -void ap_update_connection_status(long conn_id, const char *key, - const char *value) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; - } - i++; - } - if (i >= STATUSES_PER_CONNECTION) { - return; - } - apr_cpystrn(ss->key, key, KEY_LENGTH); - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; -} - -void ap_reset_connection_status(long conn_id) -{ - if (maintain_connection_status) { - ap_mpmt_beos_force_reset_connection_status(conn_id); - } -} - -void ap_mpmt_beos_set_maintain_connection_status(int flag) { - maintain_connection_status = flag; - return; -} - -void ap_mpmt_beos_force_reset_connection_status(long conn_id) -{ - int i; - - for (i = 0; i < STATUSES_PER_CONNECTION; i++) { - ap_scoreboard_image->table[conn_id][i].key[0] = '\0'; - } -} - -const char *ap_get_connection_status(long conn_id, const char *key) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return ""; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - return ss->value; - } - } - - return NULL; -} - -apr_array_header_t *ap_get_connections(apr_pool_t *p) -{ - int i; - apr_array_header_t *connection_list; - long *array_slot; - - connection_list = apr_make_array(p, 0, sizeof(long)); - for (i = 0; i < ap_max_daemons_limit * HARD_THREAD_LIMIT; i++) { - if (ap_scoreboard_image->table[i][0].key[0] != '\0') { - array_slot = apr_push_array(connection_list); - *array_slot = i; - } - } - return connection_list; -} - -apr_array_header_t *ap_get_connection_keys(apr_pool_t *p, long conn_id) -{ - int i = 0; - status_table_entry *ss; - apr_array_header_t *key_list; - char **array_slot; - - key_list = apr_make_array(p, 0, KEY_LENGTH * sizeof(char)); - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - array_slot = apr_push_array(key_list); - *array_slot = apr_pstrdup(p, ss->key); - i++; - } - return key_list; -} - -apr_array_header_t *ap_get_status_table(apr_pool_t *p) -{ - int i, j; - apr_array_header_t *server_status; - ap_status_table_row_t *array_slot; - status_table_entry *ss; - - server_status = apr_make_array(p, 0, sizeof(ap_status_table_row_t)); - - for (i = 0; i < ap_max_daemons_limit * HARD_THREAD_LIMIT; i++) { - if (ap_scoreboard_image->table[i][0].key[0] == '\0') - continue; - array_slot = apr_push_array(server_status); - array_slot->data = apr_make_table(p, 0); - array_slot->conn_id = i; - - for (j = 0; j < STATUSES_PER_CONNECTION; j++) { - ss = &(ap_scoreboard_image->table[i][j]); - if (ss->key[0] != '\0') { - apr_table_add(array_slot->data, ss->key, ss->value); - } - else { - break; - } - } - } - return server_status; -} diff --git a/server/mpm/mpmt_beos/scoreboard.h b/server/mpm/mpmt_beos/scoreboard.h deleted file mode 100644 index 084fb9b3a8..0000000000 --- a/server/mpm/mpmt_beos/scoreboard.h +++ /dev/null @@ -1,103 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef MPMT_BEOS_SCOREBOARD_H -#define MPMT_BEOS_SCOREBOARD_H -#ifdef __cplusplus -extern "C" { -#endif - - -#include -#include "mpm_default.h" /* For HARD_.*_LIMIT */ - -AP_DECLARE(int) ap_exists_scoreboard_image(void); -void reinit_scoareboard(apr_pool_t *p); -void cleanup_scoreboard(void); -void ap_mpmt_beos_set_maintain_connection_status(int flag); -void ap_mpmt_beos_force_reset_connection_status(long conn_id); -void reinit_scoreboard(apr_pool_t *p); -void update_scoreboard_global(void); -AP_DECLARE(int) find_child_by_pid(int pid); -int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r); -void ap_time_process_request(int child_num, int thread_num, int status); - -/* Add support for connection table functions */ - -#define KEY_LENGTH 16 -#define VALUE_LENGTH 64 - -typedef struct { - char key[KEY_LENGTH]; - char value[VALUE_LENGTH]; -} status_table_entry; - -#define STATUSES_PER_CONNECTION 10 - -typedef struct { - status_table_entry - table[HARD_SERVER_LIMIT*HARD_THREAD_LIMIT][STATUSES_PER_CONNECTION]; -} scoreboard; - -#define SCOREBOARD_SIZE sizeof(scoreboard) - -#ifdef __cplusplus -} -#endif - -#endif /* !MPMT_BEOS_SCOREBOARD_H */ diff --git a/server/mpm/mpmt_pthread/Makefile.in b/server/mpm/mpmt_pthread/Makefile.in index ff850eb332..77f54c37a9 100644 --- a/server/mpm/mpmt_pthread/Makefile.in +++ b/server/mpm/mpmt_pthread/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libmpmt_pthread.la -LTLIBRARY_SOURCES = mpmt_pthread.c scoreboard.c +LTLIBRARY_SOURCES = mpmt_pthread.c include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/mpmt_pthread/config.m4 b/server/mpm/mpmt_pthread/config.m4 index 0c3a68c4af..e58b9a2da6 100644 --- a/server/mpm/mpmt_pthread/config.m4 +++ b/server/mpm/mpmt_pthread/config.m4 @@ -7,7 +7,4 @@ if test "$MPM_NAME" = "mpmt_pthread" ; then APACHE_MPM_PTHREAD -dnl Obsolete scoreboard code uses this. - AC_CHECK_HEADERS(sys/times.h) - AC_CHECK_FUNCS(times) fi diff --git a/server/mpm/mpmt_pthread/mpm.h b/server/mpm/mpmt_pthread/mpm.h index 3f6e43c464..3dc5187e72 100644 --- a/server/mpm/mpmt_pthread/mpm.h +++ b/server/mpm/mpmt_pthread/mpm.h @@ -70,7 +70,6 @@ extern int ap_threads_per_child; extern int ap_max_requests_per_child; -extern int ap_extended_status; extern int ap_max_daemons_limit; extern unsigned int ap_my_pid; extern server_rec *ap_server_conf; diff --git a/server/mpm/mpmt_pthread/mpm_default.h b/server/mpm/mpmt_pthread/mpm_default.h index a1e5cc3a3f..3967fd035f 100644 --- a/server/mpm/mpmt_pthread/mpm_default.h +++ b/server/mpm/mpmt_pthread/mpm_default.h @@ -59,6 +59,9 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H +#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_SERVER_LIMIT) + HARD_THREAD_LIMIT) +#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_SERVER_LIMIT), (i % HARD_THREAD_LIMIT) + /* Number of servers to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ diff --git a/server/mpm/mpmt_pthread/mpmt_pthread.c b/server/mpm/mpmt_pthread/mpmt_pthread.c index be95ecac72..2f25ec682e 100644 --- a/server/mpm/mpmt_pthread/mpmt_pthread.c +++ b/server/mpm/mpmt_pthread/mpmt_pthread.c @@ -94,13 +94,10 @@ int ap_threads_per_child=0; /* Worker threads per child */ int ap_max_requests_per_child=0; static const char *ap_pid_fname=NULL; -AP_DECLARE_DATA const char *ap_scoreboard_fname=NULL; static int ap_daemons_to_start=0; static int min_spare_threads=0; static int max_spare_threads=0; static int ap_daemons_limit=0; -static time_t ap_restart_time=0; -AP_DECLARE_DATA int ap_extended_status = 0; static int workers_may_exit = 0; static int requests_this_child; static int num_listensocks = 0; @@ -807,7 +804,7 @@ static void perform_idle_server_maintenance(void) { int i, j; int idle_thread_count; - thread_score *ss; + short_score *ss; time_t now = 0; int free_length; int free_slots[MAX_SPAWN_RATE]; @@ -933,7 +930,6 @@ static void server_main_loop(int remaining_children_to_start) /* non-fatal death... note that it's gone in the scoreboard. */ child_slot = find_child_by_pid(&pid); if (child_slot >= 0) { - ap_mpmt_pthread_force_reset_connection_status(child_slot); for (i = 0; i < ap_threads_per_child; i++) ap_update_child_status(child_slot, i, SERVER_DEAD, (request_rec *) NULL); diff --git a/server/mpm/perchild/Makefile.in b/server/mpm/perchild/Makefile.in index 4d83d72d2d..374f130646 100644 --- a/server/mpm/perchild/Makefile.in +++ b/server/mpm/perchild/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libperchild.la -LTLIBRARY_SOURCES = perchild.c scoreboard.c +LTLIBRARY_SOURCES = perchild.c include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/perchild/scoreboard.c b/server/mpm/perchild/scoreboard.c deleted file mode 100644 index 7d2e1de890..0000000000 --- a/server/mpm/perchild/scoreboard.c +++ /dev/null @@ -1,285 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * 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 "apr_strings.h" -#include "ap_config.h" -#include "httpd.h" -#include "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_config.h" -#include "unixd.h" -#include "http_conf_globals.h" -#include "mpm_status.h" -#include "scoreboard.h" -#include "mpm.h" /* for ap_max_daemons_limit */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -static scoreboard *ap_scoreboard_image = NULL; - -/***************************************************************** - * - * Dealing with the scoreboard... a lot of these variables are global - * only to avoid getting clobbered by the longjmp() that happens when - * a hard timeout expires... - * - * We begin with routines which deal with the file itself... - */ - -#if APR_HAS_SHARED_MEMORY -#include "apr_shmem.h" - -static apr_shmem_t *scoreboard_shm = NULL; - -apr_status_t ap_cleanup_shared_mem(void *d) -{ - apr_shm_free(scoreboard_shm, ap_scoreboard_image); - ap_scoreboard_image = NULL; - apr_shm_destroy(scoreboard_shm); - return APR_SUCCESS; -} - -static void setup_shared_mem(apr_pool_t *p) -{ - char buf[512]; - char errmsg[120]; - const char *fname; - apr_status_t rv; - - fname = ap_server_root_relative(p, ap_scoreboard_fname); - rv = apr_shm_init(&scoreboard_shm, SCOREBOARD_SIZE, fname, p); - if (rv != APR_SUCCESS) { - apr_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard: %s", - ap_server_argv0, apr_strerror(rv, errmsg, sizeof errmsg)); - fprintf(stderr, "%s\n", buf); - exit(APEXIT_INIT); - } - ap_scoreboard_image = apr_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE); - if (ap_scoreboard_image == NULL) { - apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard", - ap_server_argv0); - perror(buf); /* o.k. since MM sets errno */ - apr_shm_destroy(scoreboard_shm); - exit(APEXIT_INIT); - } - apr_register_cleanup(p, NULL, ap_cleanup_shared_mem, apr_null_cleanup); -} - -void reinit_scoreboard(apr_pool_t *p) -{ - if (ap_scoreboard_image == NULL) { - setup_shared_mem(p); - } - memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); -} -#endif /* APR_SHARED_MEM */ - -/**** - * Above code is shmem code. Below code is interacting with the shmem - ****/ - -static int maintain_connection_status = 1; - -void ap_perchild_set_maintain_connection_status(int flag) { - maintain_connection_status = flag; - return; -} - -/* Useful to erase the status of children that might be from previous - * generations */ -void ap_perchild_force_reset_connection_status(long conn_id) -{ - int i; - - for (i = 0; i < STATUSES_PER_CONNECTION; i++) { - ap_scoreboard_image->table[conn_id][i].key[0] = '\0'; - } -} - -void ap_reset_connection_status(long conn_id) -{ - if (maintain_connection_status) { - ap_perchild_force_reset_connection_status(conn_id); - } -} - -/* Don't mess with the string you get back from this function */ -const char *ap_get_connection_status(long conn_id, const char *key) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return ""; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - return ss->value; - } - } - - return NULL; -} - -apr_array_header_t *ap_get_connections(apr_pool_t *p) -{ - int i; - apr_array_header_t *connection_list; - long *array_slot; - - connection_list = apr_make_array(p, 0, sizeof(long)); - /* We assume that there is a connection iff it has an entry in the status - * table. Connections without any status sound problematic to me, so this - * is probably for the best. - manoj */ - for (i = 0; i < ap_max_daemons_limit*HARD_THREAD_LIMIT; i++) { - if (ap_scoreboard_image->table[i][0].key[0] != '\0') { - array_slot = apr_push_array(connection_list); - *array_slot = i; - } - } - return connection_list; -} - -apr_array_header_t *ap_get_connection_keys(apr_pool_t *p, long conn_id) -{ - int i = 0; - status_table_entry *ss; - apr_array_header_t *key_list; - char **array_slot; - - key_list = apr_make_array(p, 0, KEY_LENGTH * sizeof(char)); - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - array_slot = apr_push_array(key_list); - *array_slot = apr_pstrdup(p, ss->key); - i++; - } - return key_list; -} - -/* Note: no effort is made here to prevent multiple threads from messing with - * a single connection at the same time. ap_update_connection_status should - * only be called by the thread that owns the connection */ - -void ap_update_connection_status(long conn_id, const char *key, - const char *value) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; - } - i++; - } - /* Not found. Add an entry for this value */ - if (i >= STATUSES_PER_CONNECTION) { - /* No room. Oh well, not much anyone can do about it. */ - return; - } - apr_cpystrn(ss->key, key, KEY_LENGTH); - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; -} - -apr_array_header_t *ap_get_status_table(apr_pool_t *p) -{ - int i, j; - apr_array_header_t *server_status; - ap_status_table_row_t *array_slot; - status_table_entry *ss; - - server_status = apr_make_array(p, 0, sizeof(ap_status_table_row_t)); - - /* Go ahead and return what's in the connection status table even if we - * aren't maintaining it. We can at least look at what children from - * previous generations are up to. */ - - for (i = 0; i < ap_max_daemons_limit*HARD_THREAD_LIMIT; i++) { - if (ap_scoreboard_image->table[i][0].key[0] == '\0') - continue; - array_slot = apr_push_array(server_status); - array_slot->data = apr_make_table(p, 0); - array_slot->conn_id = i; - - for (j = 0; j < STATUSES_PER_CONNECTION; j++) { - ss = &(ap_scoreboard_image->table[i][j]); - if (ss->key[0] != '\0') { - apr_table_add(array_slot->data, ss->key, ss->value); - } - else { - break; - } - } - } - return server_status; -} diff --git a/server/mpm/perchild/scoreboard.h b/server/mpm/perchild/scoreboard.h deleted file mode 100644 index a610f19e40..0000000000 --- a/server/mpm/perchild/scoreboard.h +++ /dev/null @@ -1,108 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef APACHE_SCOREBOARD_H -#define APACHE_SCOREBOARD_H -#include -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef TPF -#include -#else -#include -#endif /* TPF */ - -#include "mpm_default.h" /* For HARD_.*_LIMIT */ - -/* The generic shared memory chunk code */ -void reinit_scoreboard(apr_pool_t *p); - -AP_DECLARE(void) reopen_scoreboard(apr_pool_t *p); - -/* The stuff for perchild's status table */ - -#include "mpm_status.h" - -void ap_perchild_set_maintain_connection_status(int flag); -void ap_perchild_force_reset_connection_status(long conn_id); -#define KEY_LENGTH 16 -#define VALUE_LENGTH 64 -typedef struct { - char key[KEY_LENGTH]; - char value[VALUE_LENGTH]; -} status_table_entry; - -#define STATUSES_PER_CONNECTION 10 - -typedef struct { - status_table_entry - table[HARD_SERVER_LIMIT*HARD_THREAD_LIMIT][STATUSES_PER_CONNECTION]; -} scoreboard; - -#define SCOREBOARD_SIZE sizeof(scoreboard) - -AP_DECLARE_DATA extern const char *ap_scoreboard_fname; -apr_status_t ap_cleanup_shared_mem(void *d); - -#ifdef __cplusplus -} -#endif - -#endif /* !APACHE_SCOREBOARD_H */ diff --git a/server/mpm/prefork/config.m4 b/server/mpm/prefork/config.m4 index 4d839c7b8e..30093874d1 100644 --- a/server/mpm/prefork/config.m4 +++ b/server/mpm/prefork/config.m4 @@ -4,7 +4,4 @@ dnl Turn off all threading functions in APR APACHE_FAST_OUTPUT(server/mpm/$MPM_NAME/Makefile) -dnl Obsolete scoreboard code uses this. - AC_CHECK_HEADERS(sys/times.h) - AC_CHECK_FUNCS(times) fi diff --git a/server/mpm/prefork/mpm.h b/server/mpm/prefork/mpm.h index d458c8a0c2..ed1f96175b 100644 --- a/server/mpm/prefork/mpm.h +++ b/server/mpm/prefork/mpm.h @@ -71,6 +71,7 @@ #define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) #define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) +extern int ap_threads_per_child; extern int ap_max_daemons_limit; extern scoreboard *ap_scoreboard_image; extern server_rec *ap_server_conf; diff --git a/server/mpm/prefork/mpm_default.h b/server/mpm/prefork/mpm_default.h index a9cbdfa384..8e1ca00717 100644 --- a/server/mpm/prefork/mpm_default.h +++ b/server/mpm/prefork/mpm_default.h @@ -59,6 +59,10 @@ #ifndef APACHE_MPM_DEFAULT_H #define APACHE_MPM_DEFAULT_H +#define AP_ID_FROM_CHILD_THREAD(c, t) c +#define AP_CHILD_THREAD_FROM_ID(i) i, 0 + + /* Number of servers to spawn off by default --- also, if fewer than * this free when the caretaker checks, it will spawn more. */ @@ -95,6 +99,10 @@ #define HARD_SERVER_LIMIT 256 #endif +#ifndef HARD_THREAD_LIMIT +#define HARD_THREAD_LIMIT 1 +#endif + /* File used for accept locking, when we use a file */ #ifndef DEFAULT_LOCKFILE #define DEFAULT_LOCKFILE "logs/accept.lock" diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 7db36c0b28..63e4d97a9e 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -82,7 +82,6 @@ /* TODO: this is a cobbled together prefork MPM example... it should mostly * TODO: behave like apache-1.3... here's a short list of things I think * TODO: need cleaning up still: - * TODO: - clean up scoreboard stuff when we figure out how to do it in 2.0 */ #include "apr.h" @@ -105,7 +104,6 @@ #include "ap_config.h" #include "httpd.h" #include "mpm_default.h" -#include "mpm_status.h" #include "http_main.h" #include "http_log.h" #include "http_config.h" @@ -142,18 +140,16 @@ /* config globals */ +int ap_threads_per_child=0; /* Worker threads per child */ static int ap_max_requests_per_child=0; static const char *ap_pid_fname=NULL; static apr_lock_t *accept_lock; -static const char *ap_scoreboard_fname=NULL; static const char *ap_lock_fname; static int ap_daemons_to_start=0; static int ap_daemons_min_free=0; static int ap_daemons_max_free=0; static int ap_daemons_limit=0; -static time_t ap_restart_time=0; static int ap_extended_status = 0; -static int maintain_connection_status = 1; /* * The max child slot ever assigned, preserved across restarts. Necessary @@ -197,9 +193,6 @@ int tpf_child = 0; char tpf_server_name[INETD_SERVNAME_LENGTH+1]; #endif /* TPF */ -AP_DECLARE_DATA scoreboard *ap_scoreboard_image = NULL; -static new_scoreboard *ap_new_scoreboard_image = NULL; - #ifdef GPROF /* * change directory for gprof to plop the gmon.out file @@ -317,241 +310,11 @@ static void accept_mutex_off(void) #define SAFE_ACCEPT(stmt) do {stmt;} while(0) #endif -#if APR_HAS_SHARED_MEMORY -#include "apr_shmem.h" - -static apr_shmem_t *scoreboard_shm = NULL; -static apr_shmem_t *status_shm = NULL; - -static apr_status_t cleanup_shared_mem(void *d) -{ - apr_shm_free(scoreboard_shm, ap_scoreboard_image); - apr_shm_free(status_shm, ap_new_scoreboard_image); - ap_scoreboard_image = NULL; - ap_new_scoreboard_image = NULL; - apr_shm_destroy(scoreboard_shm); - apr_shm_destroy(status_shm); - return APR_SUCCESS; -} - -static void setup_shared_mem(apr_pool_t *p) -{ - char buf[512]; - char errmsg[120]; - const char *fname; - apr_status_t rv; - - fname = ap_server_root_relative(p, ap_scoreboard_fname); - rv = apr_shm_init(&scoreboard_shm, SCOREBOARD_SIZE, fname, p); - if (rv != APR_SUCCESS) { - apr_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard: %s", - ap_server_argv0, apr_strerror(rv, errmsg, sizeof errmsg)); - fprintf(stderr, "%s\n", buf); - exit(APEXIT_INIT); - } - ap_scoreboard_image = apr_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE); - rv = apr_shm_init(&status_shm, NEW_SCOREBOARD_SIZE, fname, p); - if (rv != APR_SUCCESS) { - apr_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard: %s", - ap_server_argv0, apr_strerror(rv, errmsg, sizeof errmsg)); - fprintf(stderr, "%s\n", buf); - exit(APEXIT_INIT); - } - ap_new_scoreboard_image = apr_shm_malloc(status_shm, NEW_SCOREBOARD_SIZE); - if (ap_scoreboard_image == NULL || ap_new_scoreboard_image == NULL) { - apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard", - ap_server_argv0); - perror(buf); /* o.k. since MM sets errno */ - apr_shm_destroy(scoreboard_shm); - apr_shm_destroy(status_shm); - exit(APEXIT_INIT); - } - apr_register_cleanup(p, NULL, cleanup_shared_mem, apr_null_cleanup); - ap_scoreboard_image->global.running_generation = 0; -} - -static void reopen_scoreboard(apr_pool_t *p) -{ -} -#endif - -/* Called by parent process */ -static void reinit_scoreboard(apr_pool_t *p) -{ - int running_gen = 0; - if (ap_scoreboard_image) - running_gen = ap_scoreboard_image->global.running_generation; - - if (ap_scoreboard_image == NULL) { - setup_shared_mem(p); - } - memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); - ap_scoreboard_image->global.running_generation = running_gen; -} - - -/* Routines called to deal with the scoreboard image - * --- note that we do *not* need write locks, since update_child_status - * only updates a *single* record in place, and only one process writes to - * a given scoreboard slot at a time (either the child process owning that - * slot, or the parent, noting that the child has died). - * - * As a final note --- setting the score entry to getpid() is always safe, - * since when the parent is writing an entry, it's only noting SERVER_DEAD - * anyway. - */ -apr_inline void ap_sync_scoreboard_image(void) -{ -#ifdef SCOREBOARD_FILE - lseek(scoreboard_fd, 0L, 0); - force_read(scoreboard_fd, ap_scoreboard_image, sizeof(*ap_scoreboard_image)) -; -#endif -} - -AP_DECLARE(int) ap_exists_scoreboard_image(void) -{ - return (ap_scoreboard_image ? 1 : 0); -} - AP_DECLARE(int) ap_get_max_daemons(void) { return ap_max_daemons_limit; } -static apr_inline void put_scoreboard_info(int child_num, - short_score *new_score_rec) -{ -#ifdef SCOREBOARD_FILE - lseek(scoreboard_fd, (long) child_num * sizeof(short_score), 0); - force_write(scoreboard_fd, new_score_rec, sizeof(short_score)); -#endif -} - -int ap_update_child_status(int child_num, int status, request_rec *r) -{ - int old_status; - short_score *ss; - - if (child_num < 0) - return -1; - - ap_check_signals(); - - ss = &ap_scoreboard_image->servers[child_num]; - old_status = ss->status; - ss->status = status; - - if (ap_extended_status) { - if (status == SERVER_READY || status == SERVER_DEAD) { - /* - * Reset individual counters - */ - if (status == SERVER_DEAD) { - ss->my_access_count = 0L; - ss->my_bytes_served = 0L; - } - ss->conn_count = (unsigned short) 0; - ss->conn_bytes = (unsigned long) 0; - } - if (r) { - conn_rec *c = r->connection; - apr_cpystrn(ss->client, ap_get_remote_host(c, r->per_dir_config, - REMOTE_NOLOOKUP), sizeof(ss->client)); - if (r->the_request == NULL) { - apr_cpystrn(ss->request, "NULL", sizeof(ss->request)); - } else if (r->parsed_uri.password == NULL) { - apr_cpystrn(ss->request, r->the_request, sizeof(ss->request)); - } else { - /* Don't reveal the password in the server-status view */ - apr_cpystrn(ss->request, apr_pstrcat(r->pool, r->method, " ", - ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITPASSWORD), - r->assbackwards ? NULL : " ", r->protocol, NULL), - sizeof(ss->request)); - } - ss->vhostrec = r->server; - } - } - if (status == SERVER_STARTING && r == NULL) { - /* clean up the slot's vhostrec pointer (maybe re-used) - * and mark the slot as belonging to a new generation. - */ - ss->vhostrec = NULL; - ap_scoreboard_image->parent[child_num].generation = ap_my_generation; -#ifdef SCOREBOARD_FILE - lseek(scoreboard_fd, XtOffsetOf(scoreboard, parent[child_num]), 0); - force_write(scoreboard_fd, &ap_scoreboard_image->parent[child_num], - sizeof(parent_score)); -#endif - } - put_scoreboard_info(child_num, ss); - - return old_status; -} - -static void update_scoreboard_global(void) -{ -#ifdef SCOREBOARD_FILE - lseek(scoreboard_fd, - (char *) &ap_scoreboard_image->global -(char *) ap_scoreboard_image, 0); - force_write(scoreboard_fd, &ap_scoreboard_image->global, - sizeof ap_scoreboard_image->global); -#endif -} - -void ap_time_process_request(int child_num, int status) -{ - short_score *ss; - - if (child_num < 0) - return; - - ap_sync_scoreboard_image(); - ss = &ap_scoreboard_image->servers[child_num]; - - if (status == START_PREQUEST) { - ss->start_time = apr_now(); - } - else if (status == STOP_PREQUEST) { - ss->stop_time = apr_now(); - } - - put_scoreboard_info(child_num, ss); -} - -/* -static void increment_counts(int child_num, request_rec *r) -{ - short_score *ss; - - ap_sync_scoreboard_image(); - ss = &ap_scoreboard_image->servers[child_num]; - -#ifdef HAVE_TIMES - times(&ss->times); -#endif - ss->access_count++; - ss->my_access_count++; - ss->conn_count++; - ss->bytes_served += r->bytes_sent; - ss->my_bytes_served += r->bytes_sent; - ss->conn_bytes += r->bytes_sent; - - put_scoreboard_info(child_num, ss); -} -*/ - -static int find_child_by_pid(apr_proc_t *pid) -{ - int i; - - for (i = 0; i < ap_max_daemons_limit; ++i) - if (ap_scoreboard_image->parent[i].pid == pid->pid) - return i; - - return -1; -} - #if defined(NEED_WAITPID) /* Systems without a real waitpid sometimes lose a child's exit while waiting @@ -563,9 +326,9 @@ int reap_children(apr_wait_t *status) for (n = 0; n < ap_max_daemons_limit; ++n) { ap_sync_scoreboard_image(); - if (ap_scoreboard_image->servers[n].status != SERVER_DEAD && + if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { - ap_update_child_status(n, SERVER_DEAD, NULL); + ap_update_child_status(AP_CHILD_THREAD_FROM_ID(n), SERVER_DEAD, NULL); /* just mark it as having a successful exit status */ memset(status, 0, sizeof(apr_wait_t)); return(pid); @@ -636,7 +399,7 @@ static void restart(int sig) } restart_pending = 1; if ((is_graceful = (sig == SIGWINCH))) { - apr_kill_cleanup(pconf, NULL, cleanup_shared_mem); + apr_kill_cleanup(pconf, NULL, ap_cleanup_shared_mem); } } @@ -797,7 +560,7 @@ static void child_main(int child_num_arg) ap_child_init_hook(pchild, ap_server_conf); - (void) ap_update_child_status(my_child_num, SERVER_READY, (request_rec *) NULL); + (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL); apr_signal(SIGHUP, just_die); apr_signal(SIGTERM, just_die); @@ -831,7 +594,7 @@ static void child_main(int child_num_arg) clean_child_exit(0); } - (void) ap_update_child_status(my_child_num, SERVER_READY, (request_rec *) NULL); + (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL); /* * Wait for an acceptable connection to arrive. @@ -1043,7 +806,7 @@ static void child_main(int child_num_arg) ap_sock_disable_nagle(csd); - (void) ap_update_child_status(my_child_num, SERVER_BUSY_READ, + (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_BUSY_READ, (request_rec *) NULL); current_conn = ap_new_connection(ptrans, ap_server_conf, csd, @@ -1075,7 +838,7 @@ static int make_child(server_rec *s, int slot, time_t now) child_main(slot); } - (void) ap_update_child_status(slot, SERVER_STARTING, (request_rec *) NULL); + (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_STARTING, (request_rec *) NULL); #ifdef _OSD_POSIX @@ -1091,7 +854,7 @@ static int make_child(server_rec *s, int slot, time_t now) /* fork didn't succeed. Fix the scoreboard or else * it will say SERVER_STARTING forever and ever */ - (void) ap_update_child_status(slot, SERVER_DEAD, (request_rec *) NULL); + (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), 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 @@ -1143,7 +906,7 @@ static void startup_children(int number_to_start) time_t now = time(0); for (i = 0; number_to_start && i < ap_daemons_limit; ++i) { - if (ap_scoreboard_image->servers[i].status != SERVER_DEAD) { + if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { continue; } if (make_child(ap_server_conf, i, now) < 0) { @@ -1192,7 +955,7 @@ static void perform_idle_server_maintenance(void) if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate) break; - ss = &ap_scoreboard_image->servers[i]; + ss = &ap_scoreboard_image->servers[i][0]; status = ss->status; if (status == SERVER_DEAD) { /* try to keep children numbers as low as possible */ @@ -1307,23 +1070,6 @@ static int setup_listeners(server_rec *s) return 0; } -/* Useful to erase the status of children that might be from previous - * generations */ -static void ap_prefork_force_reset_connection_status(long conn_id) -{ - int i; - - for (i = 0; i < STATUSES_PER_CONNECTION; i++) { - ap_new_scoreboard_image->table[conn_id][i].key[0] = '\0'; - } } - -void ap_reset_connection_status(long conn_id) -{ - if (maintain_connection_status) { - ap_prefork_force_reset_connection_status(conn_id); - } -} - /***************************************************************** * Executive routines. */ @@ -1406,8 +1152,7 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ap_sync_scoreboard_image(); child_slot = find_child_by_pid(&pid); if (child_slot >= 0) { - ap_prefork_force_reset_connection_status(child_slot); - (void) ap_update_child_status(child_slot, SERVER_DEAD, + (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(child_slot), SERVER_DEAD, (request_rec *) NULL); if (remaining_children_to_start && child_slot < ap_daemons_limit) { @@ -1521,8 +1266,8 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) */ ap_sync_scoreboard_image(); for (i = 0; i < ap_daemons_limit; ++i) { - if (ap_scoreboard_image->servers[i].status != SERVER_DEAD) { - ap_scoreboard_image->servers[i].status = SERVER_GRACEFUL; + if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { + ap_scoreboard_image->servers[i][0].status = SERVER_GRACEFUL; } } #endif @@ -1726,131 +1471,6 @@ static const char *set_coredumpdir (cmd_parms *cmd, void *dummy, const char *arg return NULL; } -/* Stub functions until this MPM supports the connection status API */ -/* Don't mess with the string you get back from this function */ -const char *ap_get_connection_status(long conn_id, const char *key) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return ""; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_new_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - return ss->value; - } - } - - return NULL; -} - -apr_array_header_t *ap_get_connections(apr_pool_t *p) -{ - int i; - apr_array_header_t *connection_list; - long *array_slot; - - connection_list = apr_make_array(p, 0, sizeof(long)); - /* We assume that there is a connection iff it has an entry in the status - * table. Connections without any status sound problematic to me, so this - * is probably for the best. - manoj */ - for (i = 0; i < ap_max_daemons_limit; i++) { - if (ap_new_scoreboard_image->table[i][0].key[0] != '\0') { - array_slot = apr_push_array(connection_list); - *array_slot = i; - } - } - return connection_list; -} - -apr_array_header_t *ap_get_connection_keys(apr_pool_t *p, long conn_id) -{ - int i = 0; - status_table_entry *ss; - apr_array_header_t *key_list; - char **array_slot; - - key_list = apr_make_array(p, 0, KEY_LENGTH * sizeof(char)); - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_new_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - array_slot = apr_push_array(key_list); - *array_slot = apr_pstrdup(p, ss->key); - i++; - } - return key_list; -} - -/* Note: no effort is made here to prevent multiple threads from messing with - * a single connection at the same time. ap_update_connection_status should - * only be called by the thread that owns the connection */ - -void ap_update_connection_status(long conn_id, const char *key, - const char *value) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_new_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - if (0 == strcmp(ss->key, key)) { - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; - } - i++; - } - /* Not found. Add an entry for this value */ - if (i >= STATUSES_PER_CONNECTION) { - /* No room. Oh well, not much anyone can do about it. */ - return; - } - apr_cpystrn(ss->key, key, KEY_LENGTH); - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; -} - -apr_array_header_t *ap_get_status_table(apr_pool_t *p) -{ - int i, j; - apr_array_header_t *server_status; - ap_status_table_row_t *array_slot; - status_table_entry *ss; - - server_status = apr_make_array(p, 0, sizeof(ap_status_table_row_t)); - - /* Go ahead and return what's in the connection status table even if we - * aren't maintaining it. We can at least look at what children from - * previous generations are up to. */ - - for (i = 0; i < ap_max_daemons_limit; i++) { - if (ap_new_scoreboard_image->table[i][0].key[0] == '\0') - continue; - array_slot = apr_push_array(server_status); - array_slot->data = apr_make_table(p, 0); - array_slot->conn_id = i; - - for (j = 0; j < STATUSES_PER_CONNECTION; j++) { - ss = &(ap_new_scoreboard_image->table[i][j]); - if (ss->key[0] != '\0') { - apr_table_add(array_slot->data, ss->key, ss->value); - } - else { - break; - } - } - } - return server_status; -} - static const command_rec prefork_cmds[] = { UNIX_DAEMON_COMMANDS LISTEN_COMMANDS diff --git a/server/mpm/prefork/scoreboard.h b/server/mpm/prefork/scoreboard.h deleted file mode 100644 index 241dc3eb12..0000000000 --- a/server/mpm/prefork/scoreboard.h +++ /dev/null @@ -1,227 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef APACHE_SCOREBOARD_H -#define APACHE_SCOREBOARD_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef WIN32 -#ifdef TPF -#include -#else -#include -#include -#endif /* TPF */ -#endif - - -/* The optimized timeout code only works if we're not using a scoreboard file - */ -#if defined(AP_USE_MEM_BASED_SCOREBOARD) -#define OPTIMIZE_TIMEOUTS -#endif - -/* Scoreboard info on a process is, for now, kept very brief --- - * just status value and pid (the latter so that the caretaker process - * can properly update the scoreboard when a process dies). We may want - * to eventually add a separate set of long_score structures which would - * give, for each process, the number of requests serviced, and info on - * the current, or most recent, request. - * - * Status values: - */ - -#define SERVER_DEAD 0 -#define SERVER_STARTING 1 /* Server Starting up */ -#define SERVER_READY 2 /* Waiting for connection (or accept() lock) */ -#define SERVER_BUSY_READ 3 /* Reading a client request */ -#define SERVER_BUSY_WRITE 4 /* Processing a client request */ -#define SERVER_BUSY_KEEPALIVE 5 /* Waiting for more requests via keepalive */ -#define SERVER_BUSY_LOG 6 /* Logging the request */ -#define SERVER_BUSY_DNS 7 /* Looking up a hostname */ -#define SERVER_GRACEFUL 8 /* server is gracefully finishing request */ -#define SERVER_NUM_STATUS 9 /* number of status settings */ - -/* A "virtual time" is simply a counter that indicates that a child is - * making progress. The parent checks up on each child, and when they have - * made progress it resets the last_rtime element. But when the child hasn't - * made progress in a time that's roughly timeout_len seconds long, it is - * sent a SIGALRM. - * - * vtime is an optimization that is used only when the scoreboard is in - * shared memory (it's not easy/feasible to do it in a scoreboard file). - * The essential observation is that timeouts rarely occur, the vast majority - * of hits finish before any timeout happens. So it really sucks to have to - * ask the operating system to set up and destroy alarms many times during - * a request. - */ -typedef unsigned vtime_t; - -/* Type used for generation indicies. Startup and every restart cause a - * new generation of children to be spawned. Children within the same - * generation share the same configuration information -- pointers to stuff - * created at config time in the parent are valid across children. For - * example, the vhostrec pointer in the scoreboard below is valid in all - * children of the same generation. - * - * The safe way to access the vhost pointer is like this: - * - * short_score *ss = pointer to whichver slot is interesting; - * parent_score *ps = pointer to whichver slot is interesting; - * server_rec *vh = ss->vhostrec; - * - * if (ps->generation != ap_my_generation) { - * vh = NULL; - * } - * - * then if vh is not NULL it's valid in this child. - * - * This avoids various race conditions around restarts. - */ -typedef int ap_generation_t; - -/* stuff which the children generally write, and the parent mainly reads */ -typedef struct { -#ifdef OPTIMIZE_TIMEOUTS - vtime_t cur_vtime; /* the child's current vtime */ - unsigned short timeout_len; /* length of the timeout */ -#endif - unsigned char status; - unsigned long access_count; - unsigned long bytes_served; - unsigned long my_access_count; - unsigned long my_bytes_served; - unsigned long conn_bytes; - unsigned short conn_count; - apr_time_t start_time; - apr_time_t stop_time; -#ifdef HAVE_TIMES - struct tms times; -#endif -#ifndef OPTIMIZE_TIMEOUTS - time_t last_used; -#endif - char client[32]; /* Keep 'em small... */ - char request[64]; /* We just want an idea... */ - server_rec *vhostrec; /* What virtual host is being accessed? */ - /* SEE ABOVE FOR SAFE USAGE! */ -} short_score; - -typedef struct { - ap_generation_t running_generation; /* the generation of children which - * should still be serving requests. */ -} global_score; - -/* stuff which the parent generally writes and the children rarely read */ -typedef struct { - pid_t pid; -#ifdef OPTIMIZE_TIMEOUTS - time_t last_rtime; /* time(0) of the last change */ - vtime_t last_vtime; /* the last vtime the parent has seen */ -#endif - ap_generation_t generation; /* generation of this child */ -} parent_score; - -typedef struct { - short_score servers[HARD_SERVER_LIMIT]; - parent_score parent[HARD_SERVER_LIMIT]; - global_score global; -} scoreboard; - -#define KEY_LENGTH 16 -#define VALUE_LENGTH 64 -typedef struct { - char key[KEY_LENGTH]; - char value[VALUE_LENGTH]; } status_table_entry; - -#define STATUSES_PER_CONNECTION 10 - -typedef struct { - status_table_entry - table[HARD_SERVER_LIMIT][STATUSES_PER_CONNECTION]; -} new_scoreboard; - -#define SCOREBOARD_SIZE sizeof(scoreboard) -#define NEW_SCOREBOARD_SIZE sizeof(new_scoreboard) -#ifdef TPF -#define SCOREBOARD_NAME "SCOREBRD" -#define SCOREBOARD_FRAMES SCOREBOARD_SIZE/4095 + 1 -#endif - -AP_DECLARE(void) ap_sync_scoreboard_image(void); -AP_DECLARE(int) ap_exists_scoreboard_image(void); - -AP_DECLARE_DATA extern scoreboard *ap_scoreboard_image; - -AP_DECLARE_DATA extern ap_generation_t volatile ap_my_generation; - -/* for time_process_request() in http_main.c */ -#define START_PREQUEST 1 -#define STOP_PREQUEST 2 - -int ap_update_child_status(int child_num, int status, request_rec *r); -void ap_time_process_request(int child_num, int status); - -#ifdef __cplusplus -} -#endif - -#endif /* !APACHE_SCOREBOARD_H */ diff --git a/server/mpm/spmt_os2/scoreboard.h b/server/mpm/spmt_os2/scoreboard.h deleted file mode 100644 index d1d77e9c30..0000000000 --- a/server/mpm/spmt_os2/scoreboard.h +++ /dev/null @@ -1,204 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000 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 - * . - * - * Portions of this software are based upon public domain software - * originally written at the National Center for Supercomputing Applications, - * University of Illinois, Urbana-Champaign. - */ - -#ifndef APACHE_SCOREBOARD_H -#define APACHE_SCOREBOARD_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_SYS_TIMES_H -#include -#endif - -/* The optimized timeout code only works if we're not using a scoreboard file - */ -#if defined(AP_USE_MEM_BASED_SCOREBOARD) -#define OPTIMIZE_TIMEOUTS -#endif - -/* Scoreboard info on a thread is, for now, kept very brief --- - * just status value and pid (the latter so that the caretaker thread - * can properly update the scoreboard when a thread dies). We may want - * to eventually add a separate set of long_score structures which would - * give, for each thread, the number of requests serviced, and info on - * the current, or most recent, request. - * - * Status values: - */ - -#define SERVER_DEAD 0 -#define SERVER_STARTING 1 /* Server Starting up */ -#define SERVER_READY 2 /* Waiting for connection (or accept() lock) */ -#define SERVER_BUSY_READ 3 /* Reading a client request */ -#define SERVER_BUSY_WRITE 4 /* Processing a client request */ -#define SERVER_BUSY_KEEPALIVE 5 /* Waiting for more requests via keepalive */ -#define SERVER_BUSY_LOG 6 /* Logging the request */ -#define SERVER_BUSY_DNS 7 /* Looking up a hostname */ -#define SERVER_GRACEFUL 8 /* server is gracefully finishing request */ -#define SERVER_NUM_STATUS 9 /* number of status settings */ - -/* A "virtual time" is simply a counter that indicates that a child is - * making progress. The parent checks up on each child, and when they have - * made progress it resets the last_rtime element. But when the child hasn't - * made progress in a time that's roughly timeout_len seconds long, it is - * sent a SIGALRM. - * - * vtime is an optimization that is used only when the scoreboard is in - * shared memory (it's not easy/feasible to do it in a scoreboard file). - * The essential observation is that timeouts rarely occur, the vast majority - * of hits finish before any timeout happens. So it really sucks to have to - * ask the operating system to set up and destroy alarms many times during - * a request. - */ -typedef unsigned vtime_t; - -/* Type used for generation indicies. Startup and every restart cause a - * new generation of children to be spawned. Children within the same - * generation share the same configuration information -- pointers to stuff - * created at config time in the parent are valid across children. For - * example, the vhostrec pointer in the scoreboard below is valid in all - * children of the same generation. - * - * The safe way to access the vhost pointer is like this: - * - * short_score *ss = pointer to whichver slot is interesting; - * parent_score *ps = pointer to whichver slot is interesting; - * server_rec *vh = ss->vhostrec; - * - * if (ps->generation != ap_my_generation) { - * vh = NULL; - * } - * - * then if vh is not NULL it's valid in this child. - * - * This avoids various race conditions around restarts. - */ -typedef int ap_generation_t; - -/* stuff which the children generally write, and the parent mainly reads */ -typedef struct { -#ifdef OPTIMIZE_TIMEOUTS - vtime_t cur_vtime; /* the child's current vtime */ - unsigned short timeout_len; /* length of the timeout */ -#endif - unsigned char status; - unsigned long access_count; - unsigned long bytes_served; - unsigned long my_access_count; - unsigned long my_bytes_served; - unsigned long conn_bytes; - unsigned short conn_count; - apr_time_t start_time; - apr_time_t stop_time; -#ifdef HAVE_TIMES - struct tms times; -#endif -#ifndef OPTIMIZE_TIMEOUTS - time_t last_used; -#endif - char client[32]; /* Keep 'em small... */ - char request[64]; /* We just want an idea... */ - server_rec *vhostrec; /* What virtual host is being accessed? */ - /* SEE ABOVE FOR SAFE USAGE! */ - int thread_retval; -} short_score; - -typedef struct { - ap_generation_t running_generation; /* the generation of children which - * should still be serving requests. */ -} global_score; - -/* stuff which the parent generally writes and the children rarely read */ -typedef struct { - pid_t tid; -#ifdef OPTIMIZE_TIMEOUTS - time_t last_rtime; /* time(0) of the last change */ - vtime_t last_vtime; /* the last vtime the parent has seen */ -#endif - ap_generation_t generation; /* generation of this child */ - int deferred_die; -} parent_score; - -typedef struct { - short_score servers[HARD_SERVER_LIMIT]; - parent_score parent[HARD_SERVER_LIMIT]; - global_score global; -} scoreboard; - -#define SCOREBOARD_SIZE sizeof(scoreboard) -#ifdef TPF -#define SCOREBOARD_NAME "SCOREBRD" -#define SCOREBOARD_FRAMES SCOREBOARD_SIZE/4095 + 1 -#endif - -AP_DECLARE(int) ap_exists_scoreboard_image(void); - -AP_DECLARE_DATA extern scoreboard *ap_scoreboard_image; - - -/* for time_process_request() in http_main.c */ -#define START_PREQUEST 1 -#define STOP_PREQUEST 2 - -#ifdef __cplusplus -} -#endif - -#endif /* !APACHE_SCOREBOARD_H */ diff --git a/server/mpm/mpmt_pthread/scoreboard.c b/server/scoreboard.c similarity index 58% rename from server/mpm/mpmt_pthread/scoreboard.c rename to server/scoreboard.c index d701a11dbf..e36bb89222 100644 --- a/server/mpm/mpmt_pthread/scoreboard.c +++ b/server/scoreboard.c @@ -66,39 +66,27 @@ #include "http_config.h" #include "unixd.h" #include "http_conf_globals.h" -#include "mpm_status.h" #include "mpm.h" #include "scoreboard.h" #ifdef HAVE_SYS_TYPES_H #include #endif -scoreboard *ap_scoreboard_image = NULL; -new_scoreboard *ap_new_scoreboard_image = NULL; -static int maintain_connection_status = 1; -/***************************************************************** - * - * Dealing with the scoreboard... a lot of these variables are global - * only to avoid getting clobbered by the longjmp() that happens when - * a hard timeout expires... - * - * We begin with routines which deal with the file itself... - */ +AP_DECLARE_DATA scoreboard *ap_scoreboard_image = NULL; +AP_DECLARE_DATA const char *ap_scoreboard_fname=NULL; +AP_DECLARE_DATA int ap_extended_status = 0; +AP_DECLARE_DATA apr_time_t ap_restart_time = 0; #if APR_HAS_SHARED_MEMORY #include "apr_shmem.h" static apr_shmem_t *scoreboard_shm = NULL; -static apr_shmem_t *status_shm = NULL; apr_status_t ap_cleanup_shared_mem(void *d) { apr_shm_free(scoreboard_shm, ap_scoreboard_image); - apr_shm_free(status_shm, ap_new_scoreboard_image); ap_scoreboard_image = NULL; - ap_new_scoreboard_image = NULL; apr_shm_destroy(scoreboard_shm); - apr_shm_destroy(status_shm); return APR_SUCCESS; } @@ -119,20 +107,11 @@ static void setup_shared_mem(apr_pool_t *p) exit(APEXIT_INIT); } ap_scoreboard_image = apr_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE); - rv = apr_shm_init(&status_shm, NEW_SCOREBOARD_SIZE, fname, p); - if (rv != APR_SUCCESS) { - apr_snprintf(buf, sizeof(buf), "%s: could not open(create) scoreboard: %s", - ap_server_argv0, apr_strerror(rv, errmsg, sizeof errmsg)); - fprintf(stderr, "%s\n", buf); - exit(APEXIT_INIT); - } - ap_new_scoreboard_image = apr_shm_malloc(status_shm, NEW_SCOREBOARD_SIZE); - if (ap_scoreboard_image == NULL || ap_new_scoreboard_image == NULL) { + if (ap_scoreboard_image == NULL) { apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard", ap_server_argv0); perror(buf); /* o.k. since MM sets errno */ apr_shm_destroy(scoreboard_shm); - apr_shm_destroy(status_shm); exit(APEXIT_INIT); } apr_register_cleanup(p, NULL, ap_cleanup_shared_mem, apr_null_cleanup); @@ -178,12 +157,12 @@ AP_DECLARE(int) ap_exists_scoreboard_image(void) } static apr_inline void put_scoreboard_info(int child_num, int thread_num, - thread_score *new_score_rec) + short_score *new_score_rec) { /* XXX - needs to be fixed to account for threads */ #ifdef SCOREBOARD_FILE - lseek(scoreboard_fd, (long) child_num * sizeof(thread_score), 0); - force_write(scoreboard_fd, new_score_rec, sizeof(thread_score)); + lseek(scoreboard_fd, (long) child_num * sizeof(short_score), 0); + force_write(scoreboard_fd, new_score_rec, sizeof(short_score)); #endif } @@ -199,7 +178,7 @@ void update_scoreboard_global(void) void increment_counts(int child_num, int thread_num, request_rec *r) { - thread_score *ss; + short_score *ss; ss = &ap_scoreboard_image->servers[child_num][thread_num]; @@ -231,7 +210,7 @@ AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid) int ap_update_child_status(int child_num, int thread_num, int status, request_rec *r) { int old_status; - thread_score *ss; + short_score *ss; parent_score *ps; if (child_num < 0) @@ -245,7 +224,7 @@ int ap_update_child_status(int child_num, int thread_num, int status, request_re if ((status == SERVER_READY || status == SERVER_ACCEPTING) && old_status == SERVER_STARTING) { - ss->tid = pthread_self(); + ss->thread_num = child_num * HARD_SERVER_LIMIT + thread_num; ps->worker_threads = ap_threads_per_child; } @@ -286,7 +265,7 @@ int ap_update_child_status(int child_num, int thread_num, int status, request_re void ap_time_process_request(int child_num, int thread_num, int status) { - thread_score *ss; + short_score *ss; if (child_num < 0) return; @@ -302,142 +281,3 @@ void ap_time_process_request(int child_num, int thread_num, int status) put_scoreboard_info(child_num, thread_num, ss); } -/* Useful to erase the status of children that might be from previous - * generations */ -void ap_mpmt_pthread_force_reset_connection_status(long conn_id) -{ - int i; - - for (i = 0; i < STATUSES_PER_CONNECTION; i++) { ap_new_scoreboard_image->table[conn_id][i].key[0] = '\0'; - } } - -void ap_reset_connection_status(long conn_id) -{ - if (maintain_connection_status) { - ap_mpmt_pthread_force_reset_connection_status(conn_id); - } -} - -/* Don't mess with the string you get back from this function */ -const char *ap_get_connection_status(long conn_id, const char *key) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return ""; - while (i < STATUSES_PER_CONNECTION) { ss = &(ap_new_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { break; - } - if (0 == strcmp(ss->key, key)) { - return ss->value; - } - } - - return NULL; -} - -apr_array_header_t *ap_get_connections(apr_pool_t *p) -{ - int i; - apr_array_header_t *connection_list; - long *array_slot; - int max_daemons_limit = ap_get_max_daemons(); - - connection_list = apr_make_array(p, 0, sizeof(long)); - /* We assume that there is a connection iff it has an entry in the status - * table. Connections without any status sound problematic to me, so this - * is probably for the best. - manoj */ - for (i = 0; i < max_daemons_limit*HARD_THREAD_LIMIT; i++) { - if (ap_new_scoreboard_image->table[i][0].key[0] != '\0') { - array_slot = apr_push_array(connection_list); - *array_slot = i; - } - } - return connection_list; -} - -apr_array_header_t *ap_get_connection_keys(apr_pool_t *p, long conn_id) -{ - int i = 0; - status_table_entry *ss; - apr_array_header_t *key_list; - char **array_slot; - - key_list = apr_make_array(p, 0, KEY_LENGTH * sizeof(char)); - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_new_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { - break; - } - array_slot = apr_push_array(key_list); - *array_slot = apr_pstrdup(p, ss->key); - i++; - } - return key_list; -} - -/* Note: no effort is made here to prevent multiple threads from messing with - * a single connection at the same time. ap_update_connection_status should - * only be called by the thread that owns the connection */ - -void ap_update_connection_status(long conn_id, const char *key, - const char *value) -{ - int i = 0; - status_table_entry *ss; - - if (!maintain_connection_status) return; - while (i < STATUSES_PER_CONNECTION) { - ss = &(ap_new_scoreboard_image->table[conn_id][i]); - if (ss->key[0] == '\0') { break; - } if (0 == strcmp(ss->key, key)) { - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; - } - i++; - } - /* Not found. Add an entry for this value */ - if (i >= STATUSES_PER_CONNECTION) { - /* No room. Oh well, not much anyone can do about it. */ - return; - } - apr_cpystrn(ss->key, key, KEY_LENGTH); - apr_cpystrn(ss->value, value, VALUE_LENGTH); - return; -} - -apr_array_header_t *ap_get_status_table(apr_pool_t *p) -{ - int i, j; - apr_array_header_t *server_status; - ap_status_table_row_t *array_slot; - int max_daemons_limit = ap_get_max_daemons(); - status_table_entry *ss; - - server_status = apr_make_array(p, 0, sizeof(ap_status_table_row_t)); - - /* Go ahead and return what's in the connection status table even if we - * aren't maintaining it. We can at least look at what children from - * previous generations are up to. */ - - for (i = 0; i < max_daemons_limit*HARD_THREAD_LIMIT; i++) { - if (ap_new_scoreboard_image->table[i][0].key[0] == '\0') - continue; - array_slot = apr_push_array(server_status); - array_slot->data = apr_make_table(p, 0); - array_slot->conn_id = i; - - for (j = 0; j < STATUSES_PER_CONNECTION; j++) { - ss = &(ap_new_scoreboard_image->table[i][j]); - if (ss->key[0] != '\0') { - apr_table_add(array_slot->data, ss->key, ss->value); - } - else { - break; - } - } - } - return server_status; -} - -