Changes with Apache 2.0.14-dev
+ *) Allow modules to query the MPM about it's execution profile. This
+ query API can and should be extended in the future, but for now,
+ max_daemons, and threading or forking is a very good start.
+ [Jon Travis <jtravis@covalent.net>]
+
*) Modify mod_include to send blocks of data no larger than 9k.
Without this, mod_include will wait until the whole file is parsed,
or the first tag is found to send any data to the client.
*/
AP_DECLARE(int) ap_graceful_stop_signalled(void);
-/**
- * Get the maximum number of daemons processes for this version of Apache
- * @return The maximum number of daemon processes
- * @deffunc int ap_get_max_daemons(void)
- */
-AP_DECLARE(int) ap_get_max_daemons(void);
-
/**
* Spawn a process with privileges that another module has requested
* @param r The request_rec of the current request
apr_pool_t *p);
+#define AP_MPMQ_MAX_DAEMONS 1 /* Max # of daemons */
+#define AP_MPMQ_IS_THREADED 2 /* MPM can do threading */
+#define AP_MPMQ_IS_FORKED 3 /* MPM can do forking */
+
+/**
+ * Query a property of the current MPM.
+ * @param query_code One of APM_MPMQ_*
+ * @param result A location to place the result of the query
+ * @return APR_SUCCESS or APR_ENOTIMPL
+ * @deffunc int ap_mpm_query(int query_code, int *result)
+ */
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result);
+
#endif
#include "apr_lib.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
+#include "ap_mpm.h"
typedef struct {
const char *name; /* matching module name */
}
if (!r->args || !strcasecmp(r->args, "server")) {
+ int max_daemons, forked, threaded;
+
ap_rprintf(r, "<a name=\"server\"><strong>Server Version:</strong> "
"<font size=+1><tt>%s</tt></a></font><br>\n",
ap_get_server_version());
"<tt>connection: %d "
"keep-alive: %d</tt><br>",
serv->timeout, serv->keep_alive_timeout);
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_daemons);
+ ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded);
+ ap_mpm_query(AP_MPMQ_IS_FORKED, &forked);
+ ap_rprintf(r, "<strong>MPM Information:</strong> "
+ "<tt>Max Daemons: %d Threaded: %s Forked: %s</tt><br>\n",
+ max_daemons, threaded ? "yes" : "no",
+ forked ? "yes" : "no");
ap_rprintf(r, "<strong>Server Root:</strong> "
"<tt>%s</tt><br>\n", ap_server_root);
ap_rprintf(r, "<strong>Config File:</strong> "
int raise_sigstop_flags;
#endif
-AP_DECLARE(int) ap_get_max_daemons(void)
-{
- return ap_max_child_assigned;
-}
-
/* a clean exit from a child with proper cleanup
static void clean_child_exit(int code) __attribute__ ((noreturn)); */
static void clean_child_exit(int code)
}
}
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
+{
+ switch(query_code){
+ case AP_MPMQ_MAX_DAEMONS:
+ *result = ap_max_daemons_limit;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_THREADED:
+ *result = 1;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_FORKED:
+ *result = 1;
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
+}
+
int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
{
int remaining_threads_to_start, i,j;
static const char *lock_fname;
static apr_lock_t *thread_accept_mutex;
-AP_DECLARE(int) ap_get_max_daemons(void)
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
{
- return ap_max_daemons_limit;
+ switch(query_code){
+ case AP_MPMQ_MAX_DAEMONS:
+ *result = ap_max_daemons_limit;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_THREADED:
+ *result = 1;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_FORKED:
+ *result = 1;
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
}
/* a clean exit from a child with proper cleanup */
static const char *lock_fname;
static apr_lock_t *thread_accept_mutex;
-AP_DECLARE(int) ap_get_max_daemons(void)
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
{
- return ap_max_daemons_limit;
+ switch(query_code){
+ case AP_MPMQ_MAX_DAEMONS:
+ *result = ap_max_daemons_limit;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_THREADED:
+ *result = 1;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_FORKED:
+ *result = 1;
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
}
/* a clean exit from a child with proper cleanup */
#define SAFE_ACCEPT(stmt) do {stmt;} while(0)
#endif
-AP_DECLARE(int) ap_get_max_daemons(void)
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
{
- return ap_max_daemons_limit;
+ switch(query_code){
+ case AP_MPMQ_MAX_DAEMONS:
+ *result = ap_daemons_limit;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_THREADED:
+ *result = 0;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_FORKED:
+ *result = 1;
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
}
#if defined(NEED_WAITPID)
#define SAFE_ACCEPT(stmt) do {stmt;} while(0)
#endif
-AP_DECLARE(int) ap_get_max_daemons(void)
-{
- return max_daemons_limit;
-}
-
static int find_thread_by_tid(int tid)
{
int i;
}
}
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
+{
+ switch(query_code){
+ case AP_MPMQ_MAX_DAEMONS:
+ *result = max_daemons_limit;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_THREADED:
+ *result = 1;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_FORKED:
+ *result = 0;
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
+}
/*****************************************************************
* Executive routines.
#define SAFE_ACCEPT(stmt) (stmt)
#endif
-AP_DECLARE(int) ap_get_max_daemons(void)
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
{
- return ap_max_daemons_limit;
+ switch(query_code){
+ case AP_MPMQ_MAX_DAEMONS:
+ *result = ap_max_daemons_limit;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_THREADED:
+ *result = 1;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_FORKED:
+ *result = 1;
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
}
/* a clean exit from a child with proper cleanup */
* code
*/
ap_generation_t volatile ap_my_generation=0; /* Used by the scoreboard */
-AP_DECLARE(int) ap_get_max_daemons(void)
-{
- return 1;
-}
/* This is the helper code to resolve late bound entry points
* missing from one or more releases of the Win32 API...
* service after we preflight the config.
*/
+AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
+{
+ switch(query_code){
+ case AP_MPMQ_MAX_DAEMONS:
+ *result = MAXIMUM_WAIT_OBJECTS;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_THREADED:
+ *result = 1;
+ return APR_SUCCESS;
+ case AP_MPMQ_IS_FORKED:
+ *result = 0;
+ return APR_SUCCESS;
+ }
+ return APR_ENOTIMPL;
+}
+
static apr_status_t service_to_start_success;
static int inst_argc;
static const char * const *inst_argv;
apr_status_t waitret;
int tries;
int not_dead_yet;
- int max_daemons = ap_get_max_daemons();
+ int max_daemons;
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_daemons);
MPM_SYNC_CHILD_TABLE();
for (tries = terminate ? 4 : 1; tries <= 9; ++tries) {
AP_DECLARE(int) find_child_by_pid(apr_proc_t *pid)
{
int i;
- int max_daemons_limit = ap_get_max_daemons();
+ int max_daemons_limit;
+
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_daemons_limit);
for (i = 0; i < max_daemons_limit; ++i)
if (ap_scoreboard_image->parent[i].pid == pid->pid)