Changes with Apache 2.1.0-dev
[Remove entries to the current 2.0 section below, when backported]
+
+ *) Threaded MPMs for Unix and Win32: Add WorkerStackSize directive
+ to override default thread stack size for threads which handle
+ client connections. Required for some third-party modules on
+ platforms with small default thread stack size. [Jeff Trawick]
+
*) Win32: Tweak worker thread accounting routines to eliminate
server hang when number of Listen directives in httpd.conf
is greater than or equal to the setting of ThreadsPerChild.
const char *arg);
#endif
+#ifdef AP_MPM_WANT_SET_STACKSIZE
+extern apr_size_t ap_worker_stacksize;
+extern const char *ap_mpm_set_worker_stacksize(cmd_parms *cmd, void *dummy,
+ const char *arg);
+#endif
+
#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLER
extern apr_status_t ap_fatal_signal_setup(server_rec *s, apr_pool_t *pconf);
extern apr_status_t ap_fatal_signal_child_setup(server_rec *s);
AP_INIT_TAKE1("MaxMemFree", ap_mpm_set_max_mem_free, NULL, RSRC_CONF,
"Maximum number of 1k blocks a particular childs allocator may hold."),
#endif
+#ifdef AP_MPM_WANT_SET_STACKSIZE
+AP_INIT_TAKE1("WorkerStackSize", ap_mpm_set_worker_stacksize, NULL, RSRC_CONF,
+ "Size in bytes of stack used by threads handling client connections"),
+#endif
#if AP_ENABLE_EXCEPTION_HOOK
AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF,
"Controls whether exception hook may be called after a crash"),
apr_threadattr_create(&thread_attr, pchild);
/* 0 means PTHREAD_CREATE_JOINABLE */
apr_threadattr_detach_set(thread_attr, 0);
+ if (ap_worker_stacksize != 0) {
+ apr_threadattr_stacksize_set(thread_attr, ap_worker_stacksize);
+ }
ts->threads = threads;
ts->child_num_arg = child_num_arg;
#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
#define AP_MPM_WANT_SIGNAL_SERVER
#define AP_MPM_WANT_SET_MAX_MEM_FREE
+#define AP_MPM_WANT_SET_STACKSIZE
#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER
#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
#define AP_MPM_WANT_SET_COREDUMPDIR
#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
#define AP_MPM_WANT_SIGNAL_SERVER
+#define AP_MPM_WANT_SET_STACKSIZE
#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER
#define AP_MPM_USES_POD
APR_THREAD_MUTEX_DEFAULT, pchild);
apr_threadattr_create(&worker_thread_attr, pchild);
- apr_threadattr_detach_set(worker_thread_attr, 1);
+ apr_threadattr_detach_set(worker_thread_attr, 1); if (ap_worker_stacksize != 0) {
+ apr_threadattr_stacksize_set(thread_attr, ap_worker_stacksize);
+ }
/* We are creating worker threads right now */
for (i=0; i < threads_to_start; i++) {
#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
#define AP_MPM_WANT_SIGNAL_SERVER
#define AP_MPM_WANT_SET_MAX_MEM_FREE
+#define AP_MPM_WANT_SET_STACKSIZE
#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER
#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
apr_threadattr_create(&thread_attr, pchild);
/* 0 means PTHREAD_CREATE_JOINABLE */
apr_threadattr_detach_set(thread_attr, 0);
+ if (ap_worker_stacksize != 0) {
+ apr_threadattr_stacksize_set(thread_attr, ap_worker_stacksize);
+ }
ts->threads = threads;
ts->listener = NULL;
continue;
}
ap_update_child_status_from_indexes(0, i, SERVER_STARTING, NULL);
- child_handles[i] = (HANDLE) _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) worker_main,
+ child_handles[i] = (HANDLE) _beginthreadex(NULL, (unsigned)ap_worker_stacksize,
+ (LPTHREAD_START_ROUTINE) worker_main,
(void *) i, 0, &tid);
if (child_handles[i] == 0) {
ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf,
#define AP_MPM_WANT_SET_COREDUMPDIR
#define AP_MPM_WANT_SET_SCOREBOARD
#define AP_MPM_WANT_SET_MAX_MEM_FREE
+#define AP_MPM_WANT_SET_STACKSIZE
extern int ap_threads_per_child;
extern int ap_thread_limit;
#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH
#define AP_MPM_WANT_SIGNAL_SERVER
#define AP_MPM_WANT_SET_MAX_MEM_FREE
+#define AP_MPM_WANT_SET_STACKSIZE
#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER
#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK
/* 0 means PTHREAD_CREATE_JOINABLE */
apr_threadattr_detach_set(thread_attr, 0);
+ if (ap_worker_stacksize != 0) {
+ apr_threadattr_stacksize_set(thread_attr, ap_worker_stacksize);
+ }
+
ts->threads = threads;
ts->listener = NULL;
ts->child_num_arg = child_num_arg;
#endif /* AP_MPM_WANT_SET_MAX_MEM_FREE */
+#ifdef AP_MPM_WANT_SET_STACKSIZE
+apr_size_t ap_worker_stacksize = 0; /* use system default */
+
+const char *ap_mpm_set_worker_stacksize(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ long value;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err != NULL) {
+ return err;
+ }
+
+ value = strtol(arg, NULL, 0);
+ if (value < 0 || errno == ERANGE)
+ return apr_pstrcat(cmd->pool, "Invalid WorkerStackSize value: ",
+ arg, NULL);
+
+ ap_worker_stacksize = (apr_size_t)value;
+
+ return NULL;
+}
+
+#endif /* AP_MPM_WANT_SET_STACKSIZE */
+
#ifdef AP_MPM_WANT_FATAL_SIGNAL_HANDLER
static pid_t parent_pid, my_pid;