]> granicus.if.org Git - apache/commitdiff
Change core code to allow an MPM to set hard thread/server
authorJeff Trawick <trawick@apache.org>
Tue, 18 Dec 2001 13:48:54 +0000 (13:48 +0000)
committerJeff Trawick <trawick@apache.org>
Tue, 18 Dec 2001 13:48:54 +0000 (13:48 +0000)
limits at startup.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@92512 13f79535-47bb-0310-9956-ffa450edef68

31 files changed:
CHANGES
include/ap_mmn.h
include/http_connection.h
include/httpd.h
include/scoreboard.h
modules/http/http_core.c
server/connection.c
server/core.c
server/mpm/beos/beos.c
server/mpm/beos/mpm_default.h
server/mpm/experimental/perchild/mpm.h
server/mpm/experimental/perchild/mpm_default.h
server/mpm/experimental/perchild/perchild.c
server/mpm/mpmt_os2/mpm_default.h
server/mpm/mpmt_os2/mpmt_os2.c
server/mpm/mpmt_os2/mpmt_os2_child.c
server/mpm/netware/mpm_default.h
server/mpm/netware/mpm_netware.c
server/mpm/perchild/mpm.h
server/mpm/perchild/mpm_default.h
server/mpm/perchild/perchild.c
server/mpm/prefork/mpm_default.h
server/mpm/prefork/prefork.c
server/mpm/spmt_os2/mpm_default.h
server/mpm/spmt_os2/spmt_os2.c
server/mpm/winnt/mpm_default.h
server/mpm/winnt/mpm_winnt.c
server/mpm/worker/mpm_default.h
server/mpm/worker/worker.c
server/mpm_common.c
server/scoreboard.c

diff --git a/CHANGES b/CHANGES
index 14bfd40c9bce90b5d08f39910223533883353894..ce47b5dbe8becea905298e4a823764b0c49e7e9d 100644 (file)
--- 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
index 558be523a6be4dc49c156919eabb8759ffdfd4ab..cdf2a203c1afff1d74fe0a49480668fe08c2c1db 100644 (file)
  * 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 */
index 57b043890cd1700222f07785fdf81ed6a19e69ca..5cf0ade10fc33480992a6dde70dbaa33fac8d11e 100644 (file)
@@ -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
 }
index aca094ace907b1f6bfb251e8a96fe488fd0204e2..fb1267cfd9048b086a06c15adf11ef1487281db2 100644 (file)
@@ -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... */
index 6f12fdd7525b12b34dbcc5b992a7a41e2a3e242b..6b4effdecfa34f4343b014bd863a133ff67db53a 100644 (file)
@@ -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);
index 840d187cc4315f9ebb08c18fe2c2a5047febdf15..80a23241a4ea75adf611faf2bcee90ba5243c6cc 100644 (file)
@@ -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())
index 1bc6c2bb1bb6875e089f929e007b153e57e1b9fd..9a6f5928ed0f9d18041ba7c494d9067765ded747 100644 (file)
@@ -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 */
index a5097060b8f5252a70f411e578cce572869953f5..7a0c5e0bc3bf9e9ab25ba06934d2e48780fd7ed0 100644 (file)
@@ -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).
index 484b473afc3fa57b0c205c5a26b9bc5ee2672a0b..1b21d92a620fca20a714b4471b4958e2bcef5b88 100644 (file)
 #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) {
index 6de2bb39aa37ee5d210c33c0863484050deab9ce..043f77f6915da8e6e1ea19e5ab1f8dd801ca8c3b 100644 (file)
 #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
index c1bbf0ae8fccf71821929f4d6d5dd77a1fbd2372..646a6aeae388ecf2d77450a23d145411fd9a5723 100644 (file)
@@ -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 */
index f462ea8f9014a22cd3222ed95eed1ae53ba34e48..46fb0977013164a963a041450c22e92ec3746f49 100644 (file)
@@ -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.
  */
 #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"
index fb83a84a1fae0def35e2ad8c20e5b14fff226962..c7693d1f15f1c9135fa11d7087bf60fb4f654a64 100644 (file)
 #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
index 100beb2e61f94632574a23a679f9b8a0be537a5e..67fbab0575aefa436e7060196b216132b23a9985 100644 (file)
 #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.
  */
 #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 */
index 7d04a104fcc4c83d9a1a912aa08fca6755295a41..6bb83b97dae303392eabe5d15b20b66c3eb47261 100644 (file)
 #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;
index 7e258d2695a58140cfc55c947527ede7704f08c5..8a2529957391f6579f5eb694d55a85793992db94 100644 (file)
 #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);
 }
 
 
index 7d4bfba42a75477b8859febfecdb919170ff6841..05abdf01f3f145abccc8e4f2339678c05a3ad25a 100644 (file)
@@ -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.
  */
 #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
index 2dccde33e16f05d3f916523970df0dba6800d267..60d69cf249c9c50366aeda3eea133de454d6ee46 100644 (file)
 #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) {
index c1bbf0ae8fccf71821929f4d6d5dd77a1fbd2372..646a6aeae388ecf2d77450a23d145411fd9a5723 100644 (file)
@@ -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 */
index f462ea8f9014a22cd3222ed95eed1ae53ba34e48..46fb0977013164a963a041450c22e92ec3746f49 100644 (file)
@@ -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.
  */
 #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"
index fb83a84a1fae0def35e2ad8c20e5b14fff226962..c7693d1f15f1c9135fa11d7087bf60fb4f654a64 100644 (file)
 #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
index 3763037ae6f10f5f0c10fa460b2d63206ca2ba4c..3854a2bc239977754a40cb02f13c88d8d2be263b 100644 (file)
 #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.
  */
 #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"
index b33292b1e75296b18d3701262a1b8d31246c05ea..30587fb0a2eaef98542ab8654f950ca6bc2f46cc 100644 (file)
 #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
index c554fddf60ca0b9f2a148f58e1e50cec129992d9..54cd83c3d60e893e3d3721589a67f380bb6bef8e 100644 (file)
 #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"
 #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 */
index 350d852415ce12ed9fe6a936e6f4c2d806849de2..b5b1f498b774d6c2e321000269b883da3ade6eb7 100644 (file)
 #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
index 58275cfd8d1b98e53290cf2e9fe9f635d6637209..26f8e84d9139349be5ff578a90b0c706d80d70ba 100644 (file)
@@ -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.
  */
 #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"
index 4067d5ba1b590e12e9ad95a44ac59a64bdf1712d..95d5012c245dc693c4fb7e155e4d581edcc89c01 100644 (file)
 #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);
     }
index 1d47cfe9b2c8125f62a79ad830cd5be601e5a0cf..4b9ea3acb2b508b8bef8112ecc9a4b22311645f2 100644 (file)
@@ -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.
  */
 #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
index 3d28390d37c71bd4201d37865d8687f89c3c4441..cb7e58f0206baedeaa638835cc358ae5bd86d7f2 100644 (file)
 #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;
index 57c3c037ac53f6291e5804f4b2c84eee5fb6795f..0e474928b42a210f377595122c44203a44a03c71 100644 (file)
@@ -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"
index f397900fe22113e278ad75d1c4afc2af53664296..e1c3a54c9178f29ebfd7aaca9c5a120bb174b91b 100644 (file)
@@ -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]);