From cb5c3dd6fd5e5609d23dbc7e4ede495d31110e42 Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Thu, 11 Mar 2004 03:57:50 +0000 Subject: [PATCH] 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. This is also useful for trimming back the stack size on platforms with relatively large default stack size in order to conserve address space for supporting more threads per child. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@102931 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 6 +++++ include/mpm_common.h | 6 +++++ server/core.c | 4 ++++ server/mpm/experimental/leader/leader.c | 3 +++ server/mpm/experimental/leader/mpm.h | 1 + server/mpm/experimental/perchild/mpm.h | 1 + server/mpm/experimental/perchild/perchild.c | 4 +++- server/mpm/experimental/threadpool/mpm.h | 1 + .../mpm/experimental/threadpool/threadpool.c | 3 +++ server/mpm/winnt/child.c | 3 ++- server/mpm/winnt/mpm.h | 1 + server/mpm/worker/mpm.h | 1 + server/mpm/worker/worker.c | 4 ++++ server/mpm_common.c | 24 +++++++++++++++++++ 14 files changed, 60 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 78b0370820..f598c8dde6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,12 @@ 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. diff --git a/include/mpm_common.h b/include/mpm_common.h index 8afb154ed6..f751cc64a0 100644 --- a/include/mpm_common.h +++ b/include/mpm_common.h @@ -248,6 +248,12 @@ extern const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy, 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); diff --git a/server/core.c b/server/core.c index c6d243a3a7..b62586265c 100644 --- a/server/core.c +++ b/server/core.c @@ -3225,6 +3225,10 @@ AP_INIT_TAKE1("AcceptMutex", ap_mpm_set_accept_lock_mech, NULL, RSRC_CONF, 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"), diff --git a/server/mpm/experimental/leader/leader.c b/server/mpm/experimental/leader/leader.c index ccb0c39f34..c9b275ed72 100644 --- a/server/mpm/experimental/leader/leader.c +++ b/server/mpm/experimental/leader/leader.c @@ -1074,6 +1074,9 @@ static void child_main(int child_num_arg) 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; diff --git a/server/mpm/experimental/leader/mpm.h b/server/mpm/experimental/leader/mpm.h index e9e51438dc..9ad7da214f 100644 --- a/server/mpm/experimental/leader/mpm.h +++ b/server/mpm/experimental/leader/mpm.h @@ -34,6 +34,7 @@ #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 diff --git a/server/mpm/experimental/perchild/mpm.h b/server/mpm/experimental/perchild/mpm.h index 95f3eb35f3..cb17ba9bc5 100644 --- a/server/mpm/experimental/perchild/mpm.h +++ b/server/mpm/experimental/perchild/mpm.h @@ -34,6 +34,7 @@ #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 diff --git a/server/mpm/experimental/perchild/perchild.c b/server/mpm/experimental/perchild/perchild.c index f73c0f1b43..484f630378 100644 --- a/server/mpm/experimental/perchild/perchild.c +++ b/server/mpm/experimental/perchild/perchild.c @@ -982,7 +982,9 @@ static void child_main(int child_num_arg) 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++) { diff --git a/server/mpm/experimental/threadpool/mpm.h b/server/mpm/experimental/threadpool/mpm.h index afdcce5210..ff631b067f 100644 --- a/server/mpm/experimental/threadpool/mpm.h +++ b/server/mpm/experimental/threadpool/mpm.h @@ -34,6 +34,7 @@ #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 diff --git a/server/mpm/experimental/threadpool/threadpool.c b/server/mpm/experimental/threadpool/threadpool.c index 7277915a73..fab5d99345 100644 --- a/server/mpm/experimental/threadpool/threadpool.c +++ b/server/mpm/experimental/threadpool/threadpool.c @@ -1289,6 +1289,9 @@ static void child_main(int child_num_arg) 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; diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index 76ab5b45c4..c74f41c22d 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -928,7 +928,8 @@ void child_main(apr_pool_t *pconf) 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, diff --git a/server/mpm/winnt/mpm.h b/server/mpm/winnt/mpm.h index 354d581b78..9d4ed5a9a8 100644 --- a/server/mpm/winnt/mpm.h +++ b/server/mpm/winnt/mpm.h @@ -30,6 +30,7 @@ #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; diff --git a/server/mpm/worker/mpm.h b/server/mpm/worker/mpm.h index b152569dd2..f84cbcf661 100644 --- a/server/mpm/worker/mpm.h +++ b/server/mpm/worker/mpm.h @@ -34,6 +34,7 @@ #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 diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index 90ca74119c..5080f7b523 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -1164,6 +1164,10 @@ static void child_main(int child_num_arg) /* 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; diff --git a/server/mpm_common.c b/server/mpm_common.c index afb663f296..968b4cd030 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -870,6 +870,30 @@ const char *ap_mpm_set_max_mem_free(cmd_parms *cmd, void *dummy, #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; -- 2.50.1