From: Jeff Trawick
The following table documents the names of mutexes used by httpd - and bundled modules.
- -Mutex name | -Module(s) | -Protected resource | -
---|---|---|
mpm-accept |
- incoming connections, to avoid the thundering herd problem; - for more information, refer to the - performance tuning - documentation | -|
authdigest-client |
- client list in shared memory | -|
authdigest-opaque |
- counter in shared memory | -|
ldap-cache |
- LDAP result cache | -|
rewrite-map |
- communication with external mapping programs, to avoid - intermixed I/O from multiple requests | -|
ssl-cache |
- SSL session cache | -|
ssl-stapling |
- OCSP stapling response cache | -|
watchdog-callback |
- callback function of a particular client module | -
The following mutex mechanisms are available:
default | yes
@@ -2416,8 +2361,9 @@ or specified mutexes
/path/to/mutex
and never a directory residing
on a NFS- or AFS-filesystem. The basename of the file will be the mutex
- type, an optional instance string provided by the module, with the process
- id of the httpd parent process appended to to make it unique, avoiding
+ type, an optional instance string provided by the module, and unless the
+ OmitPID
keyword is specified, the process id of the httpd
+ parent process will be appended to to make the file name unique, avoiding
conflicts when multiple httpd instances share a lock file directory. For
example, if the mutex name is mpm-accept
and the lock file
directory is /var/httpd/locks
, the lock file name for the
@@ -2432,6 +2378,64 @@ or specified mutexes
to create.
+ The following table documents the names of mutexes used by httpd + and bundled modules.
+ +Mutex name | +Module(s) | +Protected resource | +
---|---|---|
mpm-accept |
+ incoming connections, to avoid the thundering herd problem; + for more information, refer to the + performance tuning + documentation | +|
authdigest-client |
+ client list in shared memory | +|
authdigest-opaque |
+ counter in shared memory | +|
ldap-cache |
+ LDAP result cache | +|
rewrite-map |
+ communication with external mapping programs, to avoid + intermixed I/O from multiple requests | +|
ssl-cache |
+ SSL session cache | +|
ssl-stapling |
+ OCSP stapling response cache | +|
watchdog-callback |
+ callback function of a particular client module | +
The OmitPID
keyword suppresses the addition of the httpd
+ parent process id from the lock file name.
In the following example, the mutex mechanism for the MPM accept
mutex will be changed from the compiled-in default to fcntl
,
with the associated lock file created in directory
diff --git a/include/util_mutex.h b/include/util_mutex.h
index b27c7364da..e9dde52705 100644
--- a/include/util_mutex.h
+++ b/include/util_mutex.h
@@ -101,8 +101,7 @@ AP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool,
/* private function to process the Mutex directive */
AP_DECLARE_NONSTD(const char *) ap_set_mutex(cmd_parms *cmd, void *dummy,
- const char *typelist,
- const char *mechfile);
+ const char *arg);
/**
* option flags for ap_mutex_register(), ap_global_mutex_create(), and
diff --git a/server/core.c b/server/core.c
index cac5b4f373..e97a103dc8 100644
--- a/server/core.c
+++ b/server/core.c
@@ -3319,8 +3319,8 @@ AP_INIT_TAKE1("LimitRequestBody", set_limit_req_body,
AP_INIT_TAKE1("LimitXMLRequestBody", set_limit_xml_req_body, NULL, OR_ALL,
"Limit (in bytes) on maximum size of an XML-based request "
"body"),
-AP_INIT_TAKE2("Mutex", ap_set_mutex, NULL, RSRC_CONF,
- "mutex (or \"default\") and mechanism"),
+AP_INIT_RAW_ARGS("Mutex", ap_set_mutex, NULL, RSRC_CONF,
+ "mutex (or \"default\") and mechanism"),
/* System Resource Controls */
#ifdef RLIMIT_CPU
diff --git a/server/util_mutex.c b/server/util_mutex.c
index 8607a7d2ab..a3ea1d617c 100644
--- a/server/util_mutex.c
+++ b/server/util_mutex.c
@@ -125,6 +125,7 @@ typedef struct {
apr_int32_t options;
int set;
int none;
+ int omit_pid;
apr_lockmech_e mech;
const char *dir;
} mutex_cfg_t;
@@ -165,27 +166,30 @@ static void mx_hash_init(apr_pool_t *p)
}
AP_DECLARE_NONSTD(const char *)ap_set_mutex(cmd_parms *cmd, void *dummy,
- const char *type,
- const char *mechdir)
+ const char *arg)
{
apr_pool_t *p = cmd->pool;
+ const char **elt;
+ const char *mechdir;
+ const char *type;
+ int no_mutex = 0, omit_pid = 0;
+ apr_array_header_t *type_list;
apr_lockmech_e mech;
apr_status_t rv;
const char *mutexdir;
- mutex_cfg_t *mxcfg = apr_hash_get(mxcfg_by_type, type,
- APR_HASH_KEY_STRING);
+ mutex_cfg_t *mxcfg;
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
if (err != NULL) {
return err;
}
- if (!mxcfg) {
- return apr_psprintf(p, "Mutex type %s is not valid", type);
+ mechdir = ap_getword_conf(cmd->pool, &arg);
+ if (*mechdir == NULL) {
+ return "Mutex requires at least a mechanism argument ("
+ AP_ALL_AVAILABLE_MUTEXES_STRING ")";
}
- mxcfg->none = 0; /* in case that was the default */
-
rv = ap_parse_mutex(mechdir, p, &mech, &mutexdir);
if (rv == APR_ENOTIMPL) {
return apr_pstrcat(p, "Invalid Mutex argument ", mechdir,
@@ -196,20 +200,55 @@ AP_DECLARE_NONSTD(const char *)ap_set_mutex(cmd_parms *cmd, void *dummy,
return apr_pstrcat(p, "Invalid Mutex directory in argument ",
mechdir, NULL);
}
+ else if (rv == APR_ENOLOCK) { /* "none" */
+ no_mutex = 1;
+ }
+
+ /* "OmitPID" can appear at the end of the list, so build a list of
+ * mutex type names while looking for "OmitPID" (anywhere) or the end
+ */
+ type_list = apr_array_make(cmd->pool, 4, sizeof(char *));
+ while (*arg) {
+ char *s = ap_getword_conf(cmd->pool, &arg);
- mxcfg->set = 1;
- if (rv == APR_ENOLOCK) { /* "none" */
- if (!(mxcfg->options & AP_MUTEX_ALLOW_NONE)) {
- return apr_psprintf(p,
- "None is not allowed for mutex type %s",
- type);
+ if (!strcasecmp(s, "omitpid")) {
+ omit_pid = 1;
+ }
+ else {
+ char **new_type = (char **)apr_array_push(type_list);
+ *new_type = s;
}
- mxcfg->none = 1;
}
- else {
- mxcfg->mech = mech;
- if (mutexdir) { /* retain mutex default if not configured */
- mxcfg->dir = mutexdir;
+
+ if (apr_is_empty_array(type_list)) { /* no mutex type? assume "default" */
+ char **new_type = (char **)apr_array_push(type_list);
+ *new_type = "default";
+ }
+
+ while ((elt = (const char **)apr_array_pop(type_list)) != NULL) {
+ const char *type = *elt;
+ mxcfg = apr_hash_get(mxcfg_by_type, type, APR_HASH_KEY_STRING);
+ if (!mxcfg) {
+ return apr_psprintf(p, "Mutex type %s is not valid", type);
+ }
+
+ mxcfg->none = 0; /* in case that was the default */
+ mxcfg->omit_pid = omit_pid;
+
+ mxcfg->set = 1;
+ if (no_mutex) {
+ if (!(mxcfg->options & AP_MUTEX_ALLOW_NONE)) {
+ return apr_psprintf(p,
+ "None is not allowed for mutex type %s",
+ type);
+ }
+ mxcfg->none = 1;
+ }
+ else {
+ mxcfg->mech = mech;
+ if (mutexdir) { /* retain mutex default if not configured */
+ mxcfg->dir = mutexdir;
+ }
}
}
@@ -265,7 +304,9 @@ static const char *get_mutex_filename(apr_pool_t *p, mutex_cfg_t *mxcfg,
}
#if HAVE_UNISTD_H
- pid_suffix = apr_psprintf(p, ".%" APR_PID_T_FMT, getpid());
+ if (!mxcfg->omit_pid) {
+ pid_suffix = apr_psprintf(p, ".%" APR_PID_T_FMT, getpid());
+ }
#endif
return ap_server_root_relative(p,