summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--include/ap_mmn.h5
-rw-r--r--include/http_connection.h3
-rw-r--r--include/httpd.h2
-rw-r--r--include/scoreboard.h15
-rw-r--r--modules/http/http_core.c8
-rw-r--r--server/connection.c6
-rw-r--r--server/core.c8
-rw-r--r--server/mpm/beos/beos.c55
-rw-r--r--server/mpm/beos/mpm_default.h30
-rw-r--r--server/mpm/experimental/perchild/mpm.h1
-rw-r--r--server/mpm/experimental/perchild/mpm_default.h29
-rw-r--r--server/mpm/experimental/perchild/perchild.c55
-rw-r--r--server/mpm/mpmt_os2/mpm_default.h15
-rw-r--r--server/mpm/mpmt_os2/mpmt_os2.c11
-rw-r--r--server/mpm/mpmt_os2/mpmt_os2_child.c28
-rw-r--r--server/mpm/netware/mpm_default.h29
-rw-r--r--server/mpm/netware/mpm_netware.c49
-rw-r--r--server/mpm/perchild/mpm.h1
-rw-r--r--server/mpm/perchild/mpm_default.h29
-rw-r--r--server/mpm/perchild/perchild.c55
-rw-r--r--server/mpm/prefork/mpm_default.h23
-rw-r--r--server/mpm/prefork/prefork.c40
-rw-r--r--server/mpm/spmt_os2/mpm_default.h21
-rw-r--r--server/mpm/spmt_os2/spmt_os2.c39
-rw-r--r--server/mpm/winnt/mpm_default.h27
-rw-r--r--server/mpm/winnt/mpm_winnt.c38
-rw-r--r--server/mpm/worker/mpm_default.h29
-rw-r--r--server/mpm/worker/worker.c59
-rw-r--r--server/mpm_common.c1
-rw-r--r--server/scoreboard.c87
31 files changed, 460 insertions, 342 deletions
diff --git a/CHANGES b/CHANGES
index 14bfd40c9b..ce47b5dbe8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,8 @@
Changes with Apache 2.0.30-dev
+
+ *) Change core code to allow an MPM to set hard thread/server
+ limits at startup. [Jeff Trawick]
+
*) Win32: The async AcceptEx() event should be autoreset upon
successful completion of a wait (WaitForSingleObject). This
eliminates a number of spurious
diff --git a/include/ap_mmn.h b/include/ap_mmn.h
index 558be523a6..cdf2a203c1 100644
--- a/include/ap_mmn.h
+++ b/include/ap_mmn.h
@@ -83,12 +83,15 @@
* 20011127 (2.0.29-dev) bump for postconfig hook change, and removal of socket
* from connection record
* 20011212 (2.0.30-dev) bump for new used_path_info member of request_rec
+ * 20011218 (2.0.30-dev) bump for new sbh member of conn_rec, different
+ * declarations for scoreboard, new parameter to
+ * create_connection hook
*/
#define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20011212
+#define MODULE_MAGIC_NUMBER_MAJOR 20011218
#endif
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
#define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR /* backward compat */
diff --git a/include/http_connection.h b/include/http_connection.h
index 57b043890c..5cf0ade10f 100644
--- a/include/http_connection.h
+++ b/include/http_connection.h
@@ -127,10 +127,11 @@ AP_DECLARE_HOOK(int,process_connection,(conn_rec *c))
* @param csd The socket that has been accepted
* @param conn_id A unique identifier for this connection. The ID only
* needs to be unique at that time, not forever.
+ * @param sbh A handle to scoreboard information for this connection.
* @return An allocated connection record or NULL.
*/
AP_DECLARE_HOOK(conn_rec *, create_connection,
- (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id))
+ (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id, void *sbh))
#ifdef __cplusplus
}
diff --git a/include/httpd.h b/include/httpd.h
index aca094ace9..fb1267cfd9 100644
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -982,6 +982,8 @@ struct conn_rec {
struct ap_filter_t *input_filters;
/** A list of output filters to be used for this connection */
struct ap_filter_t *output_filters;
+ /** handle to scoreboard information for this connection */
+ void *sbh;
};
/* Per-vhost config... */
diff --git a/include/scoreboard.h b/include/scoreboard.h
index 6f12fdd752..6b4effdecf 100644
--- a/include/scoreboard.h
+++ b/include/scoreboard.h
@@ -70,7 +70,6 @@ extern "C" {
#endif
#include "ap_config.h"
-#include "mpm_default.h" /* For HARD_.*_LIMIT */
#include "apr_hooks.h"
#include "apr_thread_proc.h"
#include "apr_portable.h"
@@ -185,8 +184,8 @@ struct process_score{
typedef struct {
global_score global;
- process_score parent[HARD_SERVER_LIMIT];
- worker_score servers[HARD_SERVER_LIMIT][HARD_THREAD_LIMIT];
+ process_score *parent;
+ worker_score **servers;
} scoreboard;
#define KEY_LENGTH 16
@@ -196,11 +195,12 @@ typedef struct {
char value[VALUE_LENGTH];
} status_table_entry;
+/* XXX what should mod_ssl init use instead of this? */
#define SCOREBOARD_SIZE sizeof(scoreboard)
AP_DECLARE(int) ap_exists_scoreboard_image(void);
AP_DECLARE_NONSTD(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e t);
-AP_DECLARE(void) ap_increment_counts(int child_num, int thread_num, request_rec *r);
+AP_DECLARE(void) ap_increment_counts(void *sbh, request_rec *r);
apr_status_t ap_cleanup_scoreboard(void *d);
@@ -208,9 +208,14 @@ AP_DECLARE(void) reopen_scoreboard(apr_pool_t *p);
void ap_sync_scoreboard_image(void);
+AP_DECLARE(void) ap_create_sb_handle(void **new_handle, apr_pool_t *p,
+ int child_num, int thread_num);
+
void update_scoreboard_global(void);
AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid);
-AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status, request_rec *r);
+AP_DECLARE(int) ap_update_child_status(void *sbh, int status, request_rec *r);
+AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num,
+ int status, request_rec *r);
void ap_time_process_request(int child_num, int thread_num, int status);
AP_DECLARE(worker_score *) ap_get_servers_scoreboard(int x, int y);
AP_DECLARE(process_score *) ap_get_parent_scoreboard(int x);
diff --git a/modules/http/http_core.c b/modules/http/http_core.c
index 840d187cc4..80a23241a4 100644
--- a/modules/http/http_core.c
+++ b/modules/http/http_core.c
@@ -269,23 +269,23 @@ static int ap_process_http_connection(conn_rec *c)
* until no requests are left or we decide to close.
*/
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_READ, NULL);
+ ap_update_child_status(c->sbh, SERVER_BUSY_READ, NULL);
while ((r = ap_read_request(c)) != NULL) {
c->keepalive = 0;
/* process the request if it was read without error */
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_WRITE, r);
+ ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
if (r->status == HTTP_OK)
ap_process_request(r);
if (ap_extended_status)
- ap_increment_counts(AP_CHILD_THREAD_FROM_ID(c->id), r);
+ ap_increment_counts(c->sbh, r);
if (!c->keepalive || c->aborted)
break;
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_BUSY_KEEPALIVE, r);
+ ap_update_child_status(c->sbh, SERVER_BUSY_KEEPALIVE, r);
apr_pool_destroy(r->pool);
if (ap_graceful_stop_signalled())
diff --git a/server/connection.c b/server/connection.c
index 1bc6c2bb1b..9a6f5928ed 100644
--- a/server/connection.c
+++ b/server/connection.c
@@ -83,8 +83,8 @@ APR_HOOK_STRUCT(
AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_connection,(conn_rec *c),(c),OK,DECLINED)
AP_IMPLEMENT_HOOK_RUN_FIRST(int,process_connection,(conn_rec *c),(c),DECLINED)
AP_IMPLEMENT_HOOK_RUN_FIRST(conn_rec *,create_connection,
- (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id),
- (p, server, csd, conn_id), NULL)
+ (apr_pool_t *p, server_rec *server, apr_socket_t *csd, int conn_id, void *sbh),
+ (p, server, csd, conn_id, sbh), NULL)
/*
* More machine-dependent networking gooo... on some systems,
@@ -167,7 +167,7 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c)
return;
}
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(c->id), SERVER_CLOSING, NULL);
+ ap_update_child_status(c->sbh, SERVER_CLOSING, NULL);
#ifdef NO_LINGCLOSE
ap_flush_conn(c); /* just close it */
diff --git a/server/core.c b/server/core.c
index a5097060b8..7a0c5e0bc3 100644
--- a/server/core.c
+++ b/server/core.c
@@ -3426,7 +3426,7 @@ static int core_create_proxy_req(request_rec *r, request_rec *pr)
}
static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server,
- apr_socket_t *csd, int conn_id)
+ apr_socket_t *csd, int conn_id, void *sbh)
{
core_net_rec *net = apr_palloc(ptrans, sizeof(*net));
apr_status_t rv;
@@ -3438,9 +3438,9 @@ static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server,
net->in_ctx = NULL;
net->out_ctx = NULL;
net->c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec));
-
- (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(conn_id),
- SERVER_BUSY_READ, (request_rec *) NULL);
+
+ net->c->sbh = sbh;
+ (void) ap_update_child_status(net->c->sbh, SERVER_BUSY_READ, (request_rec *) NULL);
/* Got a connection structure, so initialize what fields we can
* (the rest are zeroed out by pcalloc).
diff --git a/server/mpm/beos/beos.c b/server/mpm/beos/beos.c
index 484b473afc..1b21d92a62 100644
--- a/server/mpm/beos/beos.c
+++ b/server/mpm/beos/beos.c
@@ -81,12 +81,43 @@
#include <kernel/OS.h>
#include "mpm_common.h"
#include "mpm.h"
+#include "mpm_default.h"
#include <unistd.h>
#include <sys/socket.h>
#include <signal.h>
extern int _kset_fd_limit_(int num);
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons:
+ * 1) in case something goes seriously wrong, we want to stop the server starting
+ * threads ad infinitum and crashing the server (remember that BeOS has a 192
+ * thread per team limit).
+ * 2) it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+
+/* we only ever have 1 main process running... */
+#define HARD_SERVER_LIMIT 1
+
+/* Limit on the threads per process. Clients will be locked out if more than
+ * this * HARD_SERVER_LIMIT are needed.
+ *
+ * We keep this for one reason it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifdef NO_THREADS
+#define HARD_THREAD_LIMIT 1
+#endif
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 50
+#endif
+
/*
* Actual definitions of config globals
*/
@@ -301,6 +332,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num)
conn_rec *current_conn;
long conn_id = my_child_num;
int csd;
+ void *sbh;
(void)apr_os_sock_get(&csd, sock);
@@ -313,7 +345,8 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num)
return;
}
- current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id);
+ ap_create_sb_handle(&sbh, p, 0, my_child_num);
+ current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh);
if (current_conn) {
ap_process_connection(current_conn);
@@ -352,8 +385,8 @@ static int32 worker_thread(void * dummy)
worker_thread_count++;
apr_lock_release(worker_thread_count_mutex);
- (void) ap_update_child_status(0, child_slot, SERVER_STARTING,
- (request_rec*)NULL);
+ (void) ap_update_child_status_from_indexes(0, child_slot, SERVER_STARTING,
+ (request_rec*)NULL);
apr_poll_setup(&pollset, num_listening_sockets, tpool);
for(n=0 ; n <= num_listening_sockets ; n++)
@@ -369,8 +402,8 @@ static int32 worker_thread(void * dummy)
if (this_worker_should_exit) break;
- (void) ap_update_child_status(0, child_slot, SERVER_READY,
- (request_rec*)NULL);
+ (void) ap_update_child_status_from_indexes(0, child_slot, SERVER_READY,
+ (request_rec*)NULL);
apr_lock_acquire(accept_mutex);
@@ -457,7 +490,7 @@ static int32 worker_thread(void * dummy)
apr_pool_clear(ptrans);
}
- ap_update_child_status(0, child_slot, SERVER_DEAD, (request_rec*)NULL);
+ ap_update_child_status_from_indexes(0, child_slot, SERVER_DEAD, (request_rec*)NULL);
ap_log_error(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, 0, NULL,
"worker_thread %ld exiting", find_thread(NULL));
@@ -492,7 +525,7 @@ static int make_worker(int slot)
return 0;
}
- (void) ap_update_child_status(0, slot, SERVER_STARTING, (request_rec*)NULL);
+ (void) ap_update_child_status_from_indexes(0, slot, SERVER_STARTING, (request_rec*)NULL);
tid = spawn_thread(worker_thread, "apache_worker", B_NORMAL_PRIORITY,
my_info);
if (tid < B_NO_ERROR) {
@@ -502,8 +535,8 @@ static int make_worker(int slot)
* Apache running away with the CPU trying to fork over and
* over and over again.
*/
- (void) ap_update_child_status(0, slot, SERVER_DEAD,
- (request_rec*)NULL);
+ (void) ap_update_child_status_from_indexes(0, slot, SERVER_DEAD,
+ (request_rec*)NULL);
sleep(10);
free(my_info);
@@ -627,7 +660,9 @@ static void server_main_loop(int remaining_threads_to_start)
}
if (child_slot >= 0) {
ap_scoreboard_image->servers[0][child_slot].tid = 0;
- (void) ap_update_child_status(0, child_slot, SERVER_DEAD, (request_rec*)NULL);
+ (void) ap_update_child_status_from_indexes(0, child_slot,
+ SERVER_DEAD,
+ (request_rec*)NULL);
if (remaining_threads_to_start
&& child_slot < ap_thread_limit) {
diff --git a/server/mpm/beos/mpm_default.h b/server/mpm/beos/mpm_default.h
index 6de2bb39aa..043f77f691 100644
--- a/server/mpm/beos/mpm_default.h
+++ b/server/mpm/beos/mpm_default.h
@@ -71,36 +71,6 @@
#define DEFAULT_START_THREADS 10
#endif
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons:
- * 1) in case something goes seriously wrong, we want to stop the server starting
- * threads ad infinitum and crashing the server (remember that BeOS has a 192
- * thread per team limit).
- * 2) it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-
-/* we only ever have 1 main process running... */
-#define HARD_SERVER_LIMIT 1
-
-/* Limit on the threads per process. Clients will be locked out if more than
- * this * HARD_SERVER_LIMIT are needed.
- *
- * We keep this for one reason it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifdef NO_THREADS
-#define HARD_THREAD_LIMIT 1
-#endif
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 50
-#endif
-
#ifdef NO_THREADS
#define DEFAULT_THREADS 1
#endif
diff --git a/server/mpm/experimental/perchild/mpm.h b/server/mpm/experimental/perchild/mpm.h
index c1bbf0ae8f..646a6aeae3 100644
--- a/server/mpm/experimental/perchild/mpm.h
+++ b/server/mpm/experimental/perchild/mpm.h
@@ -93,7 +93,6 @@ typedef struct 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;
#endif /* APACHE_MPM_PERCHILD_H */
diff --git a/server/mpm/experimental/perchild/mpm_default.h b/server/mpm/experimental/perchild/mpm_default.h
index f462ea8f90..46fb097701 100644
--- a/server/mpm/experimental/perchild/mpm_default.h
+++ b/server/mpm/experimental/perchild/mpm_default.h
@@ -59,9 +59,6 @@
#ifndef APACHE_MPM_DEFAULT_H
#define APACHE_MPM_DEFAULT_H
-#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
-#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_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.
*/
@@ -83,38 +80,12 @@
#define DEFAULT_MIN_SPARE_THREAD 5
#endif
-/* Limit on the threads per process. Clients will be locked out if more than
- * this * HARD_SERVER_LIMIT are needed.
- *
- * We keep this for one reason it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 64
-#endif
-
/* Number of servers to spawn off by default
*/
#ifndef DEFAULT_NUM_DAEMON
#define DEFAULT_NUM_DAEMON 2
#endif
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_SERVER_LIMIT
-#define HARD_SERVER_LIMIT 8
-#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/experimental/perchild/perchild.c b/server/mpm/experimental/perchild/perchild.c
index fb83a84a1f..c7693d1f15 100644
--- a/server/mpm/experimental/perchild/perchild.c
+++ b/server/mpm/experimental/perchild/perchild.c
@@ -107,6 +107,35 @@
#include <sys/processor.h> /* for bindprocessor() */
#endif
+#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
+#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT)
+
+/* Limit on the threads per process. Clients will be locked out if more than
+ * this * HARD_SERVER_LIMIT are needed.
+ *
+ * We keep this for one reason it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 64
+#endif
+
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons --- first off,
+ * in case something goes seriously wrong, we want to stop the fork bomb
+ * short of actually crashing the machine we're running on by filling some
+ * kernel table. Secondly, it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_SERVER_LIMIT
+#define HARD_SERVER_LIMIT 8
+#endif
+
/*
* Actual definitions of config globals
*/
@@ -496,6 +525,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id)
int csd;
apr_status_t rv;
int thread_num = conn_id % HARD_THREAD_LIMIT;
+ void *sbh;
if ((rv = apr_os_sock_get(&csd, sock)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get");
@@ -515,7 +545,8 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id)
ap_sock_disable_nagle(sock);
}
- current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id);
+ ap_create_sb_handle(&sbh, p, conn_id / HARD_SERVER_LIMIT, thread_num);
+ current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh);
if (current_conn) {
ap_process_connection(current_conn);
ap_lingering_close(current_conn);
@@ -613,8 +644,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg)
apr_lock_release(thread_pool_parent_mutex);
apr_pool_create(&ptrans, tpool);
- (void) ap_update_child_status(child_num, thread_num, SERVER_STARTING,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(child_num, thread_num,
+ SERVER_STARTING,
+ (request_rec *) NULL);
apr_poll_setup(&pollset, num_listenfds+1, tpool);
for(n = 0; n <= num_listenfds; ++n) {
@@ -640,8 +672,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg)
thread_just_started = 0;
}
- (void) ap_update_child_status(child_num, thread_num, SERVER_READY,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(child_num, thread_num,
+ SERVER_READY,
+ (request_rec *) NULL);
apr_lock_acquire(thread_accept_mutex);
if (workers_may_exit) {
@@ -793,8 +826,8 @@ static void *worker_thread(apr_thread_t *thd, void *arg)
}
apr_lock_acquire(thread_pool_parent_mutex);
- ap_update_child_status(child_num, thread_num, SERVER_DEAD,
- (request_rec *) NULL);
+ ap_update_child_status_from_indexes(child_num, thread_num, SERVER_DEAD,
+ (request_rec *) NULL);
apr_pool_destroy(tpool);
apr_lock_release(thread_pool_parent_mutex);
apr_lock_acquire(worker_thread_count_mutex);
@@ -995,8 +1028,8 @@ static int make_child(server_rec *s, int slot)
ap_child_table[slot].status = SERVER_ALIVE;
child_main(slot);
}
- (void) ap_update_child_status(slot, 0, SERVER_STARTING,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING,
+ (request_rec *) NULL);
if ((pid = fork()) == -1) {
ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
@@ -1142,8 +1175,8 @@ static void server_main_loop(int remaining_children_to_start)
}
if (child_slot >= 0) {
ap_child_table[child_slot].pid = 0;
- ap_update_child_status(child_slot, i, SERVER_DEAD,
- (request_rec *) NULL);
+ ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD,
+ (request_rec *) NULL);
if (remaining_children_to_start
diff --git a/server/mpm/mpmt_os2/mpm_default.h b/server/mpm/mpmt_os2/mpm_default.h
index 100beb2e61..67fbab0575 100644
--- a/server/mpm/mpmt_os2/mpm_default.h
+++ b/server/mpm/mpmt_os2/mpm_default.h
@@ -65,17 +65,6 @@
#define DEFAULT_START_DAEMON 2
#endif
-/* We don't need many processes,
- * they're only for redundancy in the event of a crash
- */
-#define HARD_SERVER_LIMIT 10
-
-/* Limit on the total number of threads per process
- */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 256
-#endif
-
/* Maximum number of *free* server threads --- more than this, and
* they will die off.
*/
@@ -109,8 +98,4 @@
#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000
#endif
-/* AP_CHILD_THREAD_FROM_ID is used by the scoreboard. */
-#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT)
-#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
-
#endif /* AP_MPM_DEFAULT_H */
diff --git a/server/mpm/mpmt_os2/mpmt_os2.c b/server/mpm/mpmt_os2/mpmt_os2.c
index 7d04a104fc..6bb83b97da 100644
--- a/server/mpm/mpmt_os2/mpmt_os2.c
+++ b/server/mpm/mpmt_os2/mpmt_os2.c
@@ -100,6 +100,17 @@
#include <os2.h>
#include <process.h>
+/* We don't need many processes,
+ * they're only for redundancy in the event of a crash
+ */
+#define HARD_SERVER_LIMIT 10
+
+/* Limit on the total number of threads per process
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 256
+#endif
+
server_rec *ap_server_conf;
static apr_pool_t *pconf = NULL; /* Pool for config stuff */
static const char *ap_pid_fname=NULL;
diff --git a/server/mpm/mpmt_os2/mpmt_os2_child.c b/server/mpm/mpmt_os2/mpmt_os2_child.c
index 7e258d2695..8a25299573 100644
--- a/server/mpm/mpmt_os2/mpmt_os2_child.c
+++ b/server/mpm/mpmt_os2/mpmt_os2_child.c
@@ -78,6 +78,21 @@
#include <os2.h>
#include <process.h>
+/* XXXXXX move these to header file private to this MPM */
+
+/* We don't need many processes,
+ * they're only for redundancy in the event of a crash
+ */
+#define HARD_SERVER_LIMIT 10
+
+/* Limit on the total number of threads per process
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 256
+#endif
+
+#define ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
+
typedef struct {
apr_pool_t *pconn;
apr_socket_t *conn_sd;
@@ -387,6 +402,7 @@ static void worker_main(void *vpArg)
BYTE priority;
int thread_slot = (int)vpArg;
EXCEPTIONREGISTRATIONRECORD reg_rec = { NULL, thread_exception_handler };
+ void *sbh;
/* Trap exceptions in this thread so we don't take down the whole process */
DosSetExceptionHandler( &reg_rec );
@@ -400,12 +416,14 @@ static void worker_main(void *vpArg)
ap_scoreboard_image->servers[child_slot][thread_slot].tid = 0;
}
- conn_id = AP_ID_FROM_CHILD_THREAD(child_slot, thread_slot);
- ap_update_child_status(child_slot, thread_slot, SERVER_READY, NULL);
+ conn_id = ID_FROM_CHILD_THREAD(child_slot, thread_slot);
+ ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_READY,
+ NULL);
while (rc = DosReadQueue(workq, &rd, &len, (PPVOID)&worker_args, 0, DCWW_WAIT, &priority, NULLHANDLE),
rc == 0 && rd.ulData != WORKTYPE_EXIT) {
pconn = worker_args->pconn;
+ ap_create_sb_handle(&sbh, pconn, child_slot, thread_slot);
current_conn = ap_run_create_connection(pconn, ap_server_conf, worker_args->conn_sd, conn_id);
if (current_conn) {
@@ -414,10 +432,12 @@ static void worker_main(void *vpArg)
}
apr_pool_destroy(pconn);
- ap_update_child_status(child_slot, thread_slot, SERVER_READY, NULL);
+ ap_update_child_status_from_indexes(child_slot, thread_slot,
+ SERVER_READY, NULL);
}
- ap_update_child_status(child_slot, thread_slot, SERVER_DEAD, NULL);
+ ap_update_child_status_from_indexes(child_slot, thread_slot, SERVER_DEAD,
+ NULL);
}
diff --git a/server/mpm/netware/mpm_default.h b/server/mpm/netware/mpm_default.h
index 7d4bfba42a..05abdf01f3 100644
--- a/server/mpm/netware/mpm_default.h
+++ b/server/mpm/netware/mpm_default.h
@@ -59,9 +59,6 @@
#ifndef APACHE_MPM_DEFAULT_H
#define APACHE_MPM_DEFAULT_H
-#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
-#define AP_CHILD_THREAD_FROM_ID(i) (0), (i)
-
/* Number of servers to spawn off by default --- also, if fewer than
* this free when the caretaker checks, it will spawn more.
*/
@@ -83,32 +80,6 @@
#define DEFAULT_MIN_FREE_DAEMON 1
#endif
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_SERVER_LIMIT
-#define HARD_SERVER_LIMIT 1
-#endif
-
-/* Limit on the threads per process. Clients will be locked out if more than
- * this * HARD_SERVER_LIMIT are needed.
- *
- * We keep this for one reason it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 2048
-#endif
-
#ifndef DEFAULT_THREADS_PER_CHILD
#define DEFAULT_THREADS_PER_CHILD 50
#endif
diff --git a/server/mpm/netware/mpm_netware.c b/server/mpm/netware/mpm_netware.c
index 2dccde33e1..60d69cf249 100644
--- a/server/mpm/netware/mpm_netware.c
+++ b/server/mpm/netware/mpm_netware.c
@@ -125,6 +125,32 @@
#include <nks/netware.h>
#include <library.h>
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons --- first off,
+ * in case something goes seriously wrong, we want to stop the fork bomb
+ * short of actually crashing the machine we're running on by filling some
+ * kernel table. Secondly, it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_SERVER_LIMIT
+#define HARD_SERVER_LIMIT 1
+#endif
+
+/* Limit on the threads per process. Clients will be locked out if more than
+ * this * HARD_SERVER_LIMIT are needed.
+ *
+ * We keep this for one reason it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 2048
+#endif
+
#define WORKER_DEAD SERVER_DEAD
#define WORKER_STARTING SERVER_STARTING
#define WORKER_READY SERVER_READY
@@ -193,7 +219,8 @@ static void clean_child_exit(int code, int worker_num)
worker_thread_count--;
apr_thread_mutex_unlock(worker_thread_count_mutex);
if (worker_num >=0)
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(worker_num), WORKER_DEAD, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, worker_num, WORKER_DEAD,
+ (request_rec *) NULL);
NXThreadExit((void*)&code);
}
@@ -337,6 +364,7 @@ static void worker_main(void *arg)
int sockdes;
int worker_num_arg = (int)arg;
apr_pollfd_t *listen_poll;
+ void *sbh;
int my_worker_num = worker_num_arg;
apr_socket_t *csd = NULL;
@@ -358,7 +386,8 @@ static void worker_main(void *arg)
clean_child_exit(1, my_worker_num);
}
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_worker_num), WORKER_READY, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, my_worker_num, WORKER_READY,
+ (request_rec *) NULL);
while (!die_now) {
/*
@@ -372,7 +401,8 @@ static void worker_main(void *arg)
clean_child_exit(0, my_worker_num);
}
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_worker_num), WORKER_READY, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, my_worker_num, WORKER_READY,
+ (request_rec *) NULL);
/*
* Wait for an acceptable connection to arrive.
@@ -501,11 +531,13 @@ got_listener:
apr_thread_mutex_unlock(accept_mutex);
+ ap_create_sb_handle(&sbh, ptrans, 0, my_worker_num);
/*
* We now have a connection, so set it up with the appropriate
* socket options, file descriptors, and read/write buffers.
*/
- current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_worker_num);
+ current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd,
+ my_worker_num, sbh);
if (current_conn) {
ap_process_connection(current_conn);
ap_lingering_close(current_conn);
@@ -526,7 +558,8 @@ static int make_child(server_rec *s, int slot)
ap_max_workers_limit = slot + 1;
}
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), WORKER_STARTING, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, slot, WORKER_STARTING,
+ (request_rec *) NULL);
if (ctx = NXContextAlloc((void (*)(void *)) worker_main, (void*)slot, NX_PRIO_MED, ap_thread_stack_size, NX_CTX_NORMAL, &err)) {
char threadName[32];
@@ -543,7 +576,8 @@ static int make_child(server_rec *s, int slot)
/* create thread didn't succeed. Fix the scoreboard or else
* it will say SERVER_STARTING forever and ever
*/
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), WORKER_DEAD, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, slot, WORKER_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
@@ -655,7 +689,8 @@ static void perform_idle_server_maintenance(apr_pool_t *p)
* while we were counting
*/
idle_spawn_rate = 1;
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(last_non_dead), WORKER_IDLE_KILL, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, last_non_dead, WORKER_IDLE_KILL,
+ (request_rec *) NULL);
DBPRINT1("\nKilling idle thread: %d\n", last_non_dead);
}
else if (idle_count < ap_threads_min_free) {
diff --git a/server/mpm/perchild/mpm.h b/server/mpm/perchild/mpm.h
index c1bbf0ae8f..646a6aeae3 100644
--- a/server/mpm/perchild/mpm.h
+++ b/server/mpm/perchild/mpm.h
@@ -93,7 +93,6 @@ typedef struct 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;
#endif /* APACHE_MPM_PERCHILD_H */
diff --git a/server/mpm/perchild/mpm_default.h b/server/mpm/perchild/mpm_default.h
index f462ea8f90..46fb097701 100644
--- a/server/mpm/perchild/mpm_default.h
+++ b/server/mpm/perchild/mpm_default.h
@@ -59,9 +59,6 @@
#ifndef APACHE_MPM_DEFAULT_H
#define APACHE_MPM_DEFAULT_H
-#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
-#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_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.
*/
@@ -83,38 +80,12 @@
#define DEFAULT_MIN_SPARE_THREAD 5
#endif
-/* Limit on the threads per process. Clients will be locked out if more than
- * this * HARD_SERVER_LIMIT are needed.
- *
- * We keep this for one reason it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 64
-#endif
-
/* Number of servers to spawn off by default
*/
#ifndef DEFAULT_NUM_DAEMON
#define DEFAULT_NUM_DAEMON 2
#endif
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_SERVER_LIMIT
-#define HARD_SERVER_LIMIT 8
-#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/perchild/perchild.c b/server/mpm/perchild/perchild.c
index fb83a84a1f..c7693d1f15 100644
--- a/server/mpm/perchild/perchild.c
+++ b/server/mpm/perchild/perchild.c
@@ -107,6 +107,35 @@
#include <sys/processor.h> /* for bindprocessor() */
#endif
+#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
+#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_LIMIT), (i % HARD_THREAD_LIMIT)
+
+/* Limit on the threads per process. Clients will be locked out if more than
+ * this * HARD_SERVER_LIMIT are needed.
+ *
+ * We keep this for one reason it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 64
+#endif
+
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons --- first off,
+ * in case something goes seriously wrong, we want to stop the fork bomb
+ * short of actually crashing the machine we're running on by filling some
+ * kernel table. Secondly, it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_SERVER_LIMIT
+#define HARD_SERVER_LIMIT 8
+#endif
+
/*
* Actual definitions of config globals
*/
@@ -496,6 +525,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id)
int csd;
apr_status_t rv;
int thread_num = conn_id % HARD_THREAD_LIMIT;
+ void *sbh;
if ((rv = apr_os_sock_get(&csd, sock)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_os_sock_get");
@@ -515,7 +545,8 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, long conn_id)
ap_sock_disable_nagle(sock);
}
- current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id);
+ ap_create_sb_handle(&sbh, p, conn_id / HARD_SERVER_LIMIT, thread_num);
+ current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh);
if (current_conn) {
ap_process_connection(current_conn);
ap_lingering_close(current_conn);
@@ -613,8 +644,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg)
apr_lock_release(thread_pool_parent_mutex);
apr_pool_create(&ptrans, tpool);
- (void) ap_update_child_status(child_num, thread_num, SERVER_STARTING,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(child_num, thread_num,
+ SERVER_STARTING,
+ (request_rec *) NULL);
apr_poll_setup(&pollset, num_listenfds+1, tpool);
for(n = 0; n <= num_listenfds; ++n) {
@@ -640,8 +672,9 @@ static void *worker_thread(apr_thread_t *thd, void *arg)
thread_just_started = 0;
}
- (void) ap_update_child_status(child_num, thread_num, SERVER_READY,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(child_num, thread_num,
+ SERVER_READY,
+ (request_rec *) NULL);
apr_lock_acquire(thread_accept_mutex);
if (workers_may_exit) {
@@ -793,8 +826,8 @@ static void *worker_thread(apr_thread_t *thd, void *arg)
}
apr_lock_acquire(thread_pool_parent_mutex);
- ap_update_child_status(child_num, thread_num, SERVER_DEAD,
- (request_rec *) NULL);
+ ap_update_child_status_from_indexes(child_num, thread_num, SERVER_DEAD,
+ (request_rec *) NULL);
apr_pool_destroy(tpool);
apr_lock_release(thread_pool_parent_mutex);
apr_lock_acquire(worker_thread_count_mutex);
@@ -995,8 +1028,8 @@ static int make_child(server_rec *s, int slot)
ap_child_table[slot].status = SERVER_ALIVE;
child_main(slot);
}
- (void) ap_update_child_status(slot, 0, SERVER_STARTING,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING,
+ (request_rec *) NULL);
if ((pid = fork()) == -1) {
ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
@@ -1142,8 +1175,8 @@ static void server_main_loop(int remaining_children_to_start)
}
if (child_slot >= 0) {
ap_child_table[child_slot].pid = 0;
- ap_update_child_status(child_slot, i, SERVER_DEAD,
- (request_rec *) NULL);
+ ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD,
+ (request_rec *) NULL);
if (remaining_children_to_start
diff --git a/server/mpm/prefork/mpm_default.h b/server/mpm/prefork/mpm_default.h
index 3763037ae6..3854a2bc23 100644
--- a/server/mpm/prefork/mpm_default.h
+++ b/server/mpm/prefork/mpm_default.h
@@ -59,10 +59,6 @@
#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.
*/
@@ -84,25 +80,6 @@
#define DEFAULT_MIN_FREE_DAEMON 5
#endif
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_SERVER_LIMIT
-#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 b33292b1e7..30587fb0a2 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -103,6 +103,25 @@
#include <signal.h>
#include <sys/times.h>
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons --- first off,
+ * in case something goes seriously wrong, we want to stop the fork bomb
+ * short of actually crashing the machine we're running on by filling some
+ * kernel table. Secondly, it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_SERVER_LIMIT
+#define HARD_SERVER_LIMIT 256
+#endif
+
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 1
+#endif
+
/* config globals */
int ap_threads_per_child=0; /* Worker threads per child */
@@ -343,7 +362,7 @@ int reap_children(int *exitcode, apr_exit_why_e *status)
ap_sync_scoreboard_image();
if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD &&
kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) {
- ap_update_child_status(AP_CHILD_THREAD_FROM_ID(n), SERVER_DEAD, NULL);
+ ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL);
/* just mark it as having a successful exit status */
*status = APR_PROC_EXIT;
*exitcode = 0;
@@ -549,6 +568,7 @@ static void child_main(int child_num_arg)
apr_pollfd_t *pollset;
int offset;
void *csd;
+ void *sbh;
my_child_num = child_num_arg;
ap_my_pid = getpid();
@@ -572,7 +592,9 @@ static void child_main(int child_num_arg)
ap_run_child_init(pchild, ap_server_conf);
- (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL);
+ ap_create_sb_handle(&sbh, pchild, my_child_num, 0);
+
+ (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL);
ap_sync_scoreboard_image();
@@ -602,7 +624,7 @@ static void child_main(int child_num_arg)
clean_child_exit(0);
}
- (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(my_child_num), SERVER_READY, (request_rec *) NULL);
+ (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL);
/*
* Wait for an acceptable connection to arrive.
@@ -679,7 +701,7 @@ static void child_main(int child_num_arg)
* socket options, file descriptors, and read/write buffers.
*/
- current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num);
+ current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh);
if (current_conn) {
ap_process_connection(current_conn);
ap_lingering_close(current_conn);
@@ -720,7 +742,8 @@ static int make_child(server_rec *s, int slot)
child_main(slot);
}
- (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_STARTING, (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING,
+ (request_rec *) NULL);
#ifdef _OSD_POSIX
@@ -736,7 +759,8 @@ static int make_child(server_rec *s, int slot)
/* fork didn't succeed. Fix the scoreboard or else
* it will say SERVER_STARTING forever and ever
*/
- (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(slot), SERVER_DEAD, (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD,
+ (request_rec *) NULL);
/* In case system resources are maxxed out, we don't want
Apache running away with the CPU trying to fork over and
@@ -1029,8 +1053,8 @@ 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) {
- (void) ap_update_child_status(AP_CHILD_THREAD_FROM_ID(child_slot), SERVER_DEAD,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD,
+ (request_rec *) NULL);
if (remaining_children_to_start
&& child_slot < ap_daemons_limit) {
/* we're still doing a 1-for-1 replacement of dead
diff --git a/server/mpm/spmt_os2/mpm_default.h b/server/mpm/spmt_os2/mpm_default.h
index c554fddf60..54cd83c3d6 100644
--- a/server/mpm/spmt_os2/mpm_default.h
+++ b/server/mpm/spmt_os2/mpm_default.h
@@ -80,24 +80,6 @@
#define DEFAULT_MIN_FREE_DAEMON 5
#endif
-/* SPMT_OS2 only ever has 1 process */
-#define HARD_SERVER_LIMIT 1
-
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 256
-#endif
-
/* Where the main/parent process's pid is logged */
#ifndef DEFAULT_PIDLOG
#define DEFAULT_PIDLOG "logs/httpd.pid"
@@ -117,7 +99,4 @@
#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000
#endif
-/* AP_CHILD_THREAD_FROM_ID is used by the scoreboard. */
-#define AP_CHILD_THREAD_FROM_ID(i) 0, i
-
#endif /* AP_MPM_DEFAULT_H */
diff --git a/server/mpm/spmt_os2/spmt_os2.c b/server/mpm/spmt_os2/spmt_os2.c
index 350d852415..b5b1f498b7 100644
--- a/server/mpm/spmt_os2/spmt_os2.c
+++ b/server/mpm/spmt_os2/spmt_os2.c
@@ -82,6 +82,24 @@
#include <time.h>
#include <io.h>
+/* SPMT_OS2 only ever has 1 process */
+#define HARD_SERVER_LIMIT 1
+
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons --- first off,
+ * in case something goes seriously wrong, we want to stop the fork bomb
+ * short of actually crashing the machine we're running on by filling some
+ * kernel table. Secondly, it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 256
+#endif
+
/* config globals */
static int ap_daemons_to_start=0;
@@ -489,6 +507,7 @@ static void thread_main(void *thread_num_arg)
apr_pollfd_t *listen_poll;
apr_socket_t *csd = NULL;
int nsds, rv;
+ void *sbh;
/* Disable the restart signal handlers and enable the just_die stuff.
* Note that since restart() just notes that a restart has been
@@ -519,7 +538,9 @@ static void thread_main(void *thread_num_arg)
ap_run_child_init(pchild, ap_server_conf);
- (void) ap_update_child_status(0, THREAD_GLOBAL(thread_num), SERVER_READY, (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(0, THREAD_GLOBAL(thread_num),
+ SERVER_READY,
+ (request_rec *) NULL);
signal(SIGHUP, just_die);
@@ -548,7 +569,9 @@ static void thread_main(void *thread_num_arg)
clean_child_exit(0);
}
- (void) ap_update_child_status(0, THREAD_GLOBAL(thread_num), SERVER_READY, (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(0, THREAD_GLOBAL(thread_num),
+ SERVER_READY,
+ (request_rec *) NULL);
/*
* Wait for an acceptable connection to arrive.
@@ -674,6 +697,7 @@ static void thread_main(void *thread_num_arg)
*/
signal(SIGUSR1, SIG_IGN);
+ ap_create_sb_handle(&sbh, ptrans, 0, THREAD_GLOBAL(thread_num));
/*
* We now have a connection, so set it up with the appropriate
* socket options, file descriptors, and read/write buffers.
@@ -711,7 +735,8 @@ static int make_child(server_rec *s, int slot)
*ppthread_globals = parent_globals;
}
- ap_update_child_status(0, slot, SERVER_STARTING, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, slot, SERVER_STARTING,
+ (request_rec *) NULL);
if ((tid = _beginthread(thread_main, NULL, 256*1024, (void *)slot)) == -1) {
ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s, "_beginthread: Unable to create new thread");
@@ -719,7 +744,8 @@ static int make_child(server_rec *s, int slot)
/* _beginthread didn't succeed. Fix the scoreboard or else
* it will say SERVER_STARTING forever and ever
*/
- (void) ap_update_child_status(0, slot, SERVER_DEAD, (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(0, 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 _beginthread over and
@@ -1007,8 +1033,9 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
/* non-fatal death... note that it's gone in the scoreboard. */
thread_slot = find_thread_by_tid(tid);
if (thread_slot >= 0) {
- (void) ap_update_child_status(0, thread_slot, SERVER_DEAD,
- (request_rec *) NULL);
+ (void) ap_update_child_status_from_indexes(0, thread_slot,
+ SERVER_DEAD,
+ (request_rec *) NULL);
if (remaining_children_to_start
&& thread_slot < ap_daemons_limit) {
/* we're still doing a 1-for-1 replacement of dead
diff --git a/server/mpm/winnt/mpm_default.h b/server/mpm/winnt/mpm_default.h
index 58275cfd8d..26f8e84d91 100644
--- a/server/mpm/winnt/mpm_default.h
+++ b/server/mpm/winnt/mpm_default.h
@@ -59,9 +59,6 @@
#ifndef APACHE_MPM_DEFAULT_H
#define APACHE_MPM_DEFAULT_H
-/* AP_CHILD_THREAD_FROM_ID is used by the scoreboard. */
-#define AP_CHILD_THREAD_FROM_ID(i) 0, i
-
/* Number of threads to spawn off by default --- also, if fewer than
* this free when the caretaker checks, it will spawn more.
*/
@@ -83,36 +80,12 @@
#endif
*/
-/* Limit on the threads per process. Clients will be locked out if more than
- * this * HARD_SERVER_LIMIT are needed.
- *
- * We keep this for one reason it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 4096
-#endif
-
/* Number of servers to spawn off by default
*/
#ifndef DEFAULT_NUM_DAEMON
#define DEFAULT_NUM_DAEMON 1
#endif
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#define HARD_SERVER_LIMIT 1
-
/* Where the main/parent process's pid is logged */
#ifndef DEFAULT_PIDLOG
#define DEFAULT_PIDLOG "logs/httpd.pid"
diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c
index 4067d5ba1b..95d5012c24 100644
--- a/server/mpm/winnt/mpm_winnt.c
+++ b/server/mpm/winnt/mpm_winnt.c
@@ -75,6 +75,30 @@
#include "mpm_common.h"
#include <malloc.h>
+/* Limit on the threads per process. Clients will be locked out if more than
+ * this * HARD_SERVER_LIMIT are needed.
+ *
+ * We keep this for one reason it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 4096
+#endif
+
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons --- first off,
+ * in case something goes seriously wrong, we want to stop the fork bomb
+ * short of actually crashing the machine we're running on by filling some
+ * kernel table. Secondly, it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#define HARD_SERVER_LIMIT 1
+
server_rec *ap_server_conf;
typedef HANDLE thread;
@@ -863,13 +887,14 @@ static void worker_main(int thread_num)
static int requests_this_child = 0;
PCOMP_CONTEXT context = NULL;
apr_os_sock_info_t sockinfo;
+ void *sbh;
while (1) {
conn_rec *c;
apr_int32_t disconnected;
- ap_update_child_status(0, thread_num, SERVER_READY,
- (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, thread_num, SERVER_READY,
+ (request_rec *) NULL);
/* Grab a connection off the network */
@@ -900,8 +925,9 @@ static void worker_main(int thread_num)
/* ### is this correct? Shouldn't be inheritable (at this point) */
apr_os_sock_make(&context->sock, &sockinfo, context->ptrans);
+ ap_create_sb_handle(&sbh, context->ptrans, 0, thread_num);
c = ap_run_create_connection(context->ptrans, ap_server_conf, context->sock,
- thread_num);
+ thread_num, sbh);
if (c) {
ap_process_connection(c);
@@ -917,7 +943,8 @@ static void worker_main(int thread_num)
}
}
- ap_update_child_status(0, thread_num, SERVER_DEAD, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, thread_num, SERVER_DEAD,
+ (request_rec *) NULL);
ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ap_server_conf,
"Child %d: Thread exiting.", my_pid);
@@ -1023,7 +1050,8 @@ static void child_main()
"Child %d: Starting %d worker threads.", my_pid, nthreads);
child_handles = (thread) alloca(nthreads * sizeof(int));
for (i = 0; i < nthreads; i++) {
- ap_update_child_status(0, i, SERVER_STARTING, (request_rec *) NULL);
+ ap_update_child_status_from_indexes(0, i, SERVER_STARTING,
+ (request_rec *) NULL);
child_handles[i] = (thread) _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) worker_main,
(void *) i, 0, &tid);
}
diff --git a/server/mpm/worker/mpm_default.h b/server/mpm/worker/mpm_default.h
index 1d47cfe9b2..4b9ea3acb2 100644
--- a/server/mpm/worker/mpm_default.h
+++ b/server/mpm/worker/mpm_default.h
@@ -59,9 +59,6 @@
#ifndef APACHE_MPM_DEFAULT_H
#define APACHE_MPM_DEFAULT_H
-#define AP_ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
-#define AP_CHILD_THREAD_FROM_ID(i) (i / HARD_THREAD_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.
*/
@@ -83,32 +80,6 @@
#define DEFAULT_MIN_FREE_DAEMON 3
#endif
-/* Limit on the total --- clients will be locked out if more servers than
- * this are needed. It is intended solely to keep the server from crashing
- * when things get out of hand.
- *
- * We keep a hard maximum number of servers, for two reasons --- first off,
- * in case something goes seriously wrong, we want to stop the fork bomb
- * short of actually crashing the machine we're running on by filling some
- * kernel table. Secondly, it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_SERVER_LIMIT
-#define HARD_SERVER_LIMIT 16
-#endif
-
-/* Limit on the threads per process. Clients will be locked out if more than
- * this * HARD_SERVER_LIMIT are needed.
- *
- * We keep this for one reason it keeps the size of the scoreboard file small
- * enough that we can read the whole thing without worrying too much about
- * the overhead.
- */
-#ifndef HARD_THREAD_LIMIT
-#define HARD_THREAD_LIMIT 64
-#endif
-
#ifndef DEFAULT_THREADS_PER_CHILD
#define DEFAULT_THREADS_PER_CHILD 25
#endif
diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c
index 3d28390d37..cb7e58f020 100644
--- a/server/mpm/worker/worker.c
+++ b/server/mpm/worker/worker.c
@@ -106,10 +106,37 @@
#include "ap_listen.h"
#include "scoreboard.h"
#include "fdqueue.h"
+#include "mpm_default.h"
#include <signal.h>
#include <limits.h> /* for INT_MAX */
+/* Limit on the total --- clients will be locked out if more servers than
+ * this are needed. It is intended solely to keep the server from crashing
+ * when things get out of hand.
+ *
+ * We keep a hard maximum number of servers, for two reasons --- first off,
+ * in case something goes seriously wrong, we want to stop the fork bomb
+ * short of actually crashing the machine we're running on by filling some
+ * kernel table. Secondly, it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_SERVER_LIMIT
+#define HARD_SERVER_LIMIT 16
+#endif
+
+/* Limit on the threads per process. Clients will be locked out if more than
+ * this * HARD_SERVER_LIMIT are needed.
+ *
+ * We keep this for one reason it keeps the size of the scoreboard file small
+ * enough that we can read the whole thing without worrying too much about
+ * the overhead.
+ */
+#ifndef HARD_THREAD_LIMIT
+#define HARD_THREAD_LIMIT 64
+#endif
+
/*
* Actual definitions of config globals
*/
@@ -141,6 +168,8 @@ typedef struct {
apr_threadattr_t *threadattr;
} thread_starter;
+#define ID_FROM_CHILD_THREAD(c, t) ((c * HARD_THREAD_LIMIT) + t)
+
/*
* The max child slot ever assigned, preserved across restarts. Necessary
* to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We
@@ -495,9 +524,11 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num,
int my_thread_num)
{
conn_rec *current_conn;
- long conn_id = AP_ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
+ long conn_id = ID_FROM_CHILD_THREAD(my_child_num, my_thread_num);
int csd;
+ void *sbh;
+ ap_create_sb_handle(&sbh, p, my_child_num, my_thread_num);
apr_os_sock_get(&csd, sock);
if (csd >= FD_SETSIZE) {
@@ -510,7 +541,7 @@ static void process_socket(apr_pool_t *p, apr_socket_t *sock, int my_child_num,
return;
}
- current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id);
+ current_conn = ap_run_create_connection(p, ap_server_conf, sock, conn_id, sbh);
if (current_conn) {
ap_process_connection(current_conn);
ap_lingering_close(current_conn);
@@ -694,9 +725,9 @@ static void *listener_thread(apr_thread_t *thd, void * dummy)
}
}
- ap_update_child_status(process_slot, thread_slot,
- (dying) ? SERVER_DEAD : SERVER_GRACEFUL,
- (request_rec *) NULL);
+ ap_update_child_status_from_indexes(process_slot, thread_slot,
+ (dying) ? SERVER_DEAD : SERVER_GRACEFUL,
+ (request_rec *) NULL);
dying = 1;
ap_scoreboard_image->parent[process_slot].quiescing = 1;
kill(ap_my_pid, SIGTERM);
@@ -718,9 +749,9 @@ static void *worker_thread(apr_thread_t *thd, void * dummy)
free(ti);
- ap_update_child_status(process_slot, thread_slot, SERVER_STARTING, NULL);
+ ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_STARTING, NULL);
while (!workers_may_exit) {
- ap_update_child_status(process_slot, thread_slot, SERVER_READY, NULL);
+ ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL);
rv = ap_queue_pop(worker_queue, &csd, &ptrans);
/* We get FD_QUEUE_EINTR whenever ap_queue_pop() has been interrupted
* from an explicit call to ap_queue_interrupt_all(). This allows
@@ -734,7 +765,7 @@ static void *worker_thread(apr_thread_t *thd, void * dummy)
apr_pool_destroy(ptrans);
}
- ap_update_child_status(process_slot, thread_slot,
+ ap_update_child_status_from_indexes(process_slot, thread_slot,
(dying) ? SERVER_DEAD : SERVER_GRACEFUL, (request_rec *) NULL);
apr_thread_mutex_lock(worker_thread_count_mutex);
worker_thread_count--;
@@ -797,7 +828,7 @@ static void *start_threads(apr_thread_t *thd, void *dummy)
my_info->sd = 0;
/* We are creating threads right now */
- ap_update_child_status(my_child_num, i, SERVER_STARTING, NULL);
+ ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING, NULL);
/* We let each thread update its own scoreboard entry. This is
* done because it lets us deal with tid better.
*/
@@ -821,8 +852,8 @@ static void *start_threads(apr_thread_t *thd, void *dummy)
/* What state should this child_main process be listed as in the
* scoreboard...?
- * ap_update_child_status(my_child_num, i, SERVER_STARTING,
- * (request_rec *) NULL);
+ * ap_update_child_status_from_indexes(my_child_num, i, SERVER_STARTING,
+ * (request_rec *) NULL);
*
* This state should be listed separately in the scoreboard, in some kind
* of process_status, not mixed in with the worker threads' status.
@@ -965,7 +996,7 @@ static int make_child(server_rec *s, int slot)
/* fork didn't succeed. Fix the scoreboard or else
* it will say SERVER_STARTING forever and ever
*/
- ap_update_child_status(slot, 0, SERVER_DEAD, NULL);
+ ap_update_child_status_from_indexes(slot, 0, SERVER_DEAD, NULL);
/* In case system resources are maxxed out, we don't want
Apache running away with the CPU trying to fork over and
@@ -1222,8 +1253,8 @@ static void server_main_loop(int remaining_children_to_start)
child_slot = find_child_by_pid(&pid);
if (child_slot >= 0) {
for (i = 0; i < ap_threads_per_child; i++)
- ap_update_child_status(child_slot, i, SERVER_DEAD,
- (request_rec *) NULL);
+ ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD,
+ (request_rec *) NULL);
ap_scoreboard_image->parent[child_slot].pid = 0;
ap_scoreboard_image->parent[child_slot].quiescing = 0;
diff --git a/server/mpm_common.c b/server/mpm_common.c
index 57c3c037ac..0e474928b4 100644
--- a/server/mpm_common.c
+++ b/server/mpm_common.c
@@ -83,6 +83,7 @@
#include "mpm_common.h"
#include "ap_mpm.h"
#include "ap_listen.h"
+#include "mpm_default.h"
#ifdef AP_MPM_WANT_SET_SCOREBOARD
#include "scoreboard.h"
diff --git a/server/scoreboard.c b/server/scoreboard.c
index f397900fe2..e1c3a54c91 100644
--- a/server/scoreboard.c
+++ b/server/scoreboard.c
@@ -97,6 +97,14 @@ AP_IMPLEMENT_HOOK_VOID(pre_mpm,
(apr_pool_t *p, ap_scoreboard_e sb_type),
(p, sb_type))
+typedef struct sb_handle {
+ int child_num;
+ int thread_num;
+} sb_handle;
+
+static int server_limit, thread_limit;
+static apr_size_t scoreboard_size;
+
/*
* ToDo:
* This function should be renamed to cleanup_shared
@@ -115,6 +123,35 @@ static apr_status_t ap_cleanup_shared_mem(void *d)
return APR_SUCCESS;
}
+static void calc_scoreboard_size(void)
+{
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
+ scoreboard_size = sizeof(scoreboard);
+ scoreboard_size += sizeof(process_score) * server_limit;
+ scoreboard_size += sizeof(worker_score * ) * server_limit;
+ scoreboard_size += sizeof(worker_score) * server_limit * thread_limit;
+}
+
+static void init_scoreboard(void)
+{
+ char *more_storage;
+ int i;
+
+ memset(ap_scoreboard_image, 0, scoreboard_size);
+ more_storage = (char *)(ap_scoreboard_image + 1);
+ ap_scoreboard_image->parent = (process_score *)more_storage;
+ more_storage += sizeof(process_score) * server_limit;
+ ap_scoreboard_image->servers = (worker_score **)more_storage;
+ more_storage += server_limit * sizeof(worker_score *);
+
+ for (i = 0; i < server_limit; i++) {
+ ap_scoreboard_image->servers[i] = (worker_score *)more_storage;
+ more_storage += thread_limit * sizeof(worker_score);
+ }
+ ap_assert(more_storage - (char *)ap_scoreboard_image == scoreboard_size);
+}
+
/* ToDo: This function should be made to handle setting up
* a scoreboard shared between processes using any IPC technique,
* not just a shared memory segment
@@ -128,14 +165,14 @@ static void setup_shared(apr_pool_t *p)
apr_status_t rv;
fname = ap_server_root_relative(p, ap_scoreboard_fname);
- rv = apr_shm_init(&scoreboard_shm, SCOREBOARD_SIZE, fname, p);
+ 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: (%d)%s",
ap_server_argv0, rv, apr_strerror(rv, errmsg, sizeof errmsg));
fprintf(stderr, "%s\n", buf);
exit(APEXIT_INIT);
}
- ap_scoreboard_image = apr_shm_malloc(scoreboard_shm, SCOREBOARD_SIZE);
+ 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);
@@ -143,7 +180,7 @@ static void setup_shared(apr_pool_t *p)
apr_shm_destroy(scoreboard_shm);
exit(APEXIT_INIT);
}
- ap_scoreboard_image->global.running_generation = 0;
+ /* everything will be cleared shortly */
#endif
}
@@ -180,13 +217,14 @@ AP_DECLARE_NONSTD(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_t
if (ap_scoreboard_image)
running_gen = ap_scoreboard_image->global.running_generation;
if (ap_scoreboard_image == NULL) {
+ calc_scoreboard_size();
if (sb_type == SB_SHARED) {
setup_shared(p);
}
else {
/* A simple malloc will suffice */
char buf[512];
- ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE);
+ ap_scoreboard_image = (scoreboard *) malloc(scoreboard_size);
if (ap_scoreboard_image == NULL) {
apr_snprintf(buf, sizeof(buf), "%s: cannot allocate scoreboard",
ap_server_argv0);
@@ -195,7 +233,7 @@ AP_DECLARE_NONSTD(void) ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_t
}
}
}
- memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE);
+ init_scoreboard(); /* can't just memset() */
ap_scoreboard_image->global.sb_type = sb_type;
ap_scoreboard_image->global.running_generation = running_gen;
ap_restart_time = apr_time_now();
@@ -242,11 +280,12 @@ void update_scoreboard_global(void)
#endif
}
-AP_DECLARE(void) ap_increment_counts(int child_num, int thread_num, request_rec *r)
+AP_DECLARE(void) ap_increment_counts(void *sbh, request_rec *r)
{
+ sb_handle *sb = sbh;
worker_score *ws;
- ws = &ap_scoreboard_image->servers[child_num][thread_num];
+ ws = &ap_scoreboard_image->servers[sb->child_num][sb->thread_num];
#ifdef HAVE_TIMES
times(&ws->times);
@@ -258,7 +297,7 @@ AP_DECLARE(void) ap_increment_counts(int child_num, int thread_num, request_rec
ws->my_bytes_served += r->bytes_sent;
ws->conn_bytes += r->bytes_sent;
- put_scoreboard_info(child_num, thread_num, ws);
+ put_scoreboard_info(sb->child_num, sb->thread_num, ws);
}
AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid)
@@ -275,7 +314,19 @@ AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid)
return -1;
}
-AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status, request_rec *r)
+AP_DECLARE(void) ap_create_sb_handle(void **new_handle, apr_pool_t *p,
+ int child_num, int thread_num)
+{
+ sb_handle *sbh;
+
+ sbh = (sb_handle *)apr_palloc(p, sizeof *sbh);
+ *new_handle = sbh;
+ sbh->child_num = child_num;
+ sbh->thread_num = thread_num;
+}
+
+AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num,
+ int status, request_rec *r)
{
int old_status, i;
worker_score *ws;
@@ -292,9 +343,9 @@ AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status
if (status == SERVER_READY
&& old_status == SERVER_STARTING) {
- ws->thread_num = child_num * HARD_SERVER_LIMIT + thread_num;
+ ws->thread_num = child_num * server_limit + thread_num;
if (ps->generation != ap_my_generation) {
- for (i = 0; i < HARD_THREAD_LIMIT; i++) {
+ for (i = 0; i < thread_limit; i++) {
ap_scoreboard_image->servers[child_num][i].vhostrec = NULL;
}
ps->generation = ap_my_generation;
@@ -337,6 +388,14 @@ AP_DECLARE(int) ap_update_child_status(int child_num, int thread_num, int status
return old_status;
}
+AP_DECLARE(int)ap_update_child_status(void *sbh, int status, request_rec *r)
+{
+ sb_handle *sb = sbh;
+
+ return ap_update_child_status_from_indexes(sb->child_num, sb->thread_num,
+ status, r);
+}
+
void ap_time_process_request(int child_num, int thread_num, int status)
{
worker_score *ws;
@@ -357,8 +416,8 @@ void ap_time_process_request(int child_num, int thread_num, int status)
AP_DECLARE(worker_score *) ap_get_servers_scoreboard(int x, int y)
{
- if (((x < 0) || (HARD_SERVER_LIMIT < x)) ||
- ((y < 0) || (HARD_THREAD_LIMIT < y))) {
+ if (((x < 0) || (server_limit < x)) ||
+ ((y < 0) || (thread_limit < y))) {
return(NULL); /* Out of range */
}
return(&ap_scoreboard_image->servers[x][y]);
@@ -366,7 +425,7 @@ AP_DECLARE(worker_score *) ap_get_servers_scoreboard(int x, int y)
AP_DECLARE(process_score *) ap_get_parent_scoreboard(int x)
{
- if ((x < 0) || (HARD_SERVER_LIMIT < x)) {
+ if ((x < 0) || (server_limit < x)) {
return(NULL); /* Out of range */
}
return(&ap_scoreboard_image->parent[x]);