* Actual definitions of config globals
*/
-int ap_threads_per_child=HARD_THREAD_LIMIT; /* Worker threads per child */
static int ap_threads_to_start=0;
+static int ap_max_requests_per_thread = 0;
static int min_spare_threads=0;
static int max_spare_threads=0;
static int ap_thread_limit=0;
-static int num_listening_sockets = 0; /* set by open_listeners in ap_mpm_run */
+static int num_listening_sockets = 0;
static apr_socket_t ** listening_sockets;
apr_lock_t *accept_mutex = NULL;
int srv , n;
int curr_pollfd = 0, last_pollfd = 0;
sigset_t sig_mask;
- int requests_this_child = ap_max_requests_per_child;
+ int requests_this_child = ap_max_requests_per_thread;
apr_pollfd_t *pollset;
/* each worker thread is in control of its own destiny...*/
int this_worker_should_exit = 0;
If it is, you probably need more threads...
*/
- this_worker_should_exit |= (ap_max_requests_per_child != 0) && (requests_this_child <= 0);
+ this_worker_should_exit |= (ap_max_requests_per_thread != 0) && (requests_this_child <= 0);
if (this_worker_should_exit) break;
}
ap_update_child_status(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));
apr_lock_acquire(worker_thread_count_mutex);
worker_thread_count--;
*result = HARD_THREAD_LIMIT;
return APR_SUCCESS;
case AP_MPMQ_MAX_THREADS:
- *result = ap_threads_per_child;
+ *result = HARD_THREAD_LIMIT;
return APR_SUCCESS;
case AP_MPMQ_MIN_SPARE_DAEMONS:
*result = 0;
*result = min_spare_threads;
return APR_SUCCESS;
case AP_MPMQ_MAX_REQUESTS_DAEMON:
- *result = ap_max_requests_per_child;
+ *result = ap_max_requests_per_thread;
return APR_SUCCESS;
case AP_MPMQ_MAX_DAEMONS:
- *result = ap_thread_limit;
+ *result = HARD_SERVER_LIMIT;
return APR_SUCCESS;
}
return APR_ENOTIMPL;
* Startup/shutdown...
*/
- if (!is_graceful)
+ if (!is_graceful) {
+ /* setup the scoreboard shared memory */
ap_run_pre_mpm(pconf, SB_SHARED);
- if (!is_graceful) {
for (i = 0; i < HARD_SERVER_LIMIT; i++) {
ap_scoreboard_image->parent[i].pid = 0;
for (j = 0;j < HARD_THREAD_LIMIT; j++)
ap_scoreboard_image->servers[i][j].tid = 0;
}
}
+
if (HARD_SERVER_LIMIT == 1)
ap_scoreboard_image->parent[0].pid = getpid();
min_spare_threads = DEFAULT_MIN_FREE_THREADS;
max_spare_threads = DEFAULT_MAX_FREE_THREADS;
ap_thread_limit = HARD_THREAD_LIMIT;
- ap_threads_per_child = DEFAULT_THREADS_PER_CHILD;
ap_pid_fname = DEFAULT_PIDLOG;
+ ap_max_requests_per_thread = DEFAULT_MAX_REQUESTS_PER_THREAD;
ap_scoreboard_fname = DEFAULT_SCOREBOARD;
- if (!one_process)
- ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir));
}
ap_hook_pre_config(beos_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
}
-static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, const char *arg)
+static const char *set_threads_to_start(cmd_parms *cmd, void *dummy, const char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
}
ap_threads_to_start = atoi(arg);
+ if (ap_threads_to_start < 0) {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ "StartThreads set to a value less than 0, reset to 1");
+ ap_threads_to_start = 1;
+ }
return NULL;
}
return NULL;
}
-static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg)
+static const char *set_threads_limit (cmd_parms *cmd, void *dummy, const char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
}
ap_thread_limit = atoi(arg);
- if (ap_thread_limit > HARD_SERVER_LIMIT) {
+ if (ap_thread_limit > HARD_THREAD_LIMIT) {
ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
"WARNING: MaxClients of %d exceeds compile time limit "
- "of %d servers,", ap_thread_limit, HARD_SERVER_LIMIT);
+ "of %d servers,", ap_thread_limit, HARD_THREAD_LIMIT);
ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
" lowering MaxClients to %d. To increase, please "
- "see the", HARD_SERVER_LIMIT);
+ "see the", HARD_THREAD_LIMIT);
ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- " HARD_SERVER_LIMIT define in src/include/httpd.h.");
- ap_thread_limit = HARD_SERVER_LIMIT;
+ " HARD_THREAD_LIMIT define in server/mpm/beos/mpm_default.h.");
+ ap_thread_limit = HARD_THREAD_LIMIT;
}
else if (ap_thread_limit < 1) {
ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- "WARNING: Require MaxClients > 0, setting to 1");
- ap_thread_limit = 1;
+ "WARNING: Require MaxClients > 0, setting to %d", HARD_THREAD_LIMIT);
+ ap_thread_limit = HARD_THREAD_LIMIT;
}
return NULL;
}
-static const char *set_threads_per_child (cmd_parms *cmd, void *dummy, const char *arg)
+static const char *set_requests_per_thread (cmd_parms *cmd, void *dummy, const char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
return err;
}
- ap_threads_per_child = atoi(arg);
- if (ap_threads_per_child > HARD_THREAD_LIMIT) {
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- "WARNING: ThreadsPerChild of %d exceeds compile time"
- "limit of %d threads,", ap_threads_per_child,
- HARD_THREAD_LIMIT);
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- " lowering ThreadsPerChild to %d. To increase, please"
- "see the", HARD_THREAD_LIMIT);
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- " HARD_THREAD_LIMIT define in %s", AP_MPM_HARD_LIMITS_FILE);
- }
- else if (ap_threads_per_child < 1) {
- ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
- "WARNING: Require ThreadsPerChild > 0, setting to 1");
- ap_threads_per_child = 1;
+ ap_max_requests_per_thread = atoi(arg);
+ if (ap_max_requests_per_thread < 0) {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, NULL,
+ "WARNING: MaxRequestsPerThread was set below 0"
+ "reset to 0, but this may not be what you want.");
+ ap_max_requests_per_thread = 0;
}
+
return NULL;
}
static const command_rec beos_cmds[] = {
BEOS_DAEMON_COMMANDS,
LISTEN_COMMANDS,
-AP_INIT_TAKE1( "StartServers", set_daemons_to_start, NULL, RSRC_CONF,
- "Number of child processes launched at server startup"),
+AP_INIT_TAKE1( "StartThreads", set_threads_to_start, NULL, RSRC_CONF,
+ "Number of threads to launch at server startup"),
AP_INIT_TAKE1( "MinSpareThreads", set_min_spare_threads, NULL, RSRC_CONF,
"Minimum number of idle children, to handle request spikes"),
AP_INIT_TAKE1( "MaxSpareThreads", set_max_spare_threads, NULL, RSRC_CONF,
"Maximum number of idle children" ),
-AP_INIT_TAKE1( "MaxClients", set_server_limit, NULL, RSRC_CONF,
- "Maximum number of children alive at the same time" ),
-AP_INIT_TAKE1( "ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF,
- "Number of threads each child creates" ),
+AP_INIT_TAKE1( "MaxClients", set_threads_limit, NULL, RSRC_CONF,
+ "Maximum number of children alive at the same time (max threads)" ),
+AP_INIT_TAKE1( "RequestsPerThread", set_requests_per_thread, NULL, RSRC_CONF,
+ "Maximum number of requests served by a thread" ),
{ NULL }
};
* this free when the caretaker checks, it will spawn more.
*/
#ifndef DEFAULT_START_THREADS
-#define DEFAULT_START_THREADS 25
-#endif
-
-/* Maximum number of *free* threads --- more than this, and
- * they will die off.
- */
-
-#ifndef DEFAULT_MAX_FREE_THREADS
-#define DEFAULT_MAX_FREE_THREADS 50
-#endif
-
-/* Minimum --- fewer than this, and more will be created */
-
-#ifndef DEFAULT_MIN_FREE_THREADS
-#define DEFAULT_MIN_FREE_THREADS 5
+#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 --- 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.
+ * 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... */
#endif
#ifdef NO_THREADS
-#define DEFAULT_THREADS_PER_CHILD 1
+#define DEFAULT_THREADS 1
+#endif
+#ifndef DEFAULT_THREADS
+#define DEFAULT_THREADS 10
#endif
-#ifndef DEFAULT_THREADS_PER_CHILD
-#define DEFAULT_THREADS_PER_CHILD 10
+/* The following 2 settings are used to control the number of threads
+ * we have available. Normally the DEFAULT_MAX_FREE_THREADS is set
+ * to the same as the HARD_THREAD_LIMIT to avoid churning of starting
+ * new threads to replace threads killed off...
+ */
+
+/* Maximum number of *free* threads --- more than this, and
+ * they will die off.
+ */
+#ifndef DEFAULT_MAX_FREE_THREADS
+#define DEFAULT_MAX_FREE_THREADS HARD_THREAD_LIMIT
#endif
+/* Minimum --- fewer than this, and more will be created */
+#ifndef DEFAULT_MIN_FREE_THREADS
+#define DEFAULT_MIN_FREE_THREADS 1
+#endif
+
/* Where the main/parent process's pid is logged */
#ifndef DEFAULT_PIDLOG
#define DEFAULT_PIDLOG "logs/httpd.pid"
#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000
#endif
-/* Number of requests to try to handle in a single process. If <= 0,
+/* Number of requests to try to handle in a single process. If == 0,
* the children don't die off.
*/
-#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD
-#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000
+#ifndef DEFAULT_MAX_REQUESTS_PER_THREAD
+#define DEFAULT_MAX_REQUESTS_PER_THREAD 0
#endif
#endif /* AP_MPM_DEFAULT_H */