util_mutex.c revision d88a642829b2aa45e810f5bcc31be8e901b0aa3b
967e5f3c25249c779575864692935627004d3f9eChristian Maeder/* Licensed to the Apache Software Foundation (ASF) under one or more
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * contributor license agreements. See the NOTICE file distributed with
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * this work for additional information regarding copyright ownership.
75a6279dbae159d018ef812185416cf6df386c10Till Mossakowski * The ASF licenses this file to You under the Apache License, Version 2.0
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * (the "License"); you may not use this file except in compliance with
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * the License. You may obtain a copy of the License at
89054b2b95a3f92e78324dc852f3d34704e2ca49Christian Maeder * http://www.apache.org/licenses/LICENSE-2.0
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * Unless required by applicable law or agreed to in writing, software
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * distributed under the License is distributed on an "AS IS" BASIS,
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * See the License for the specific language governing permissions and
967e5f3c25249c779575864692935627004d3f9eChristian Maeder * limitations under the License.
34c05dd06c937d85e7f552e4ff0d36ca0393daeaChristian Maeder * util_mutex.c: Useful functions for determining allowable
7221c71b38c871ce66eee4537cb681d468308dfbChristian Maeder * mutexes and mutex settings
dea4c92f0c061d589c542d0640a18dab36dfbb46Christian MaederAP_DECLARE(apr_status_t) ap_parse_mutex(const char *arg, apr_pool_t *pool,
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder /* Split arg into meth and file */
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder /* APR determines temporary filename unless overridden below,
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder * we presume file indicates an mutexfile is a file path
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder * unless the method sets mutexfile=file and NULLs file
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) {
239090e32b9079422ea1ce61197557e5b816f455Christian Maeder /* NOTE: previously, 'yes' implied 'sem' */
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) {
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder else if (!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) {
7a879b08ae0ca30006f9be887a73212b07f10204Christian Maeder else if (!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) {
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder else if (!strcasecmp(meth, "posixsem") || !strcasecmp(meth, "sem")) {
09eef8548cd62d787cf3a6535f9eae10592eec89Christian Maeder /* Posix/SysV semaphores aren't file based, use the literal name
7a879b08ae0ca30006f9be887a73212b07f10204Christian Maeder * if provided and fall back on APR's default if not. Today, APR
7a879b08ae0ca30006f9be887a73212b07f10204Christian Maeder * will ignore it, but once supported it has an absurdly short limit.
7a879b08ae0ca30006f9be887a73212b07f10204Christian Maeder else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) {
adee28c3eb7bb0b9bb045d26ee6d35e19cf39053Christian Maeder /* Unless the method above assumed responsibility for setting up
adee28c3eb7bb0b9bb045d26ee6d35e19cf39053Christian Maeder * mutexfile and NULLing out file, presume it is a file we
adee28c3eb7bb0b9bb045d26ee6d35e19cf39053Christian Maeder * are looking to use
967e5f3c25249c779575864692935627004d3f9eChristian Maeder *mutexfile = ap_server_root_relative(pool, file);
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maedertypedef struct {
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder/* hash is created the first time a module calls ap_mutex_register(),
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder * rather than attempting to be the REALLY_REALLY_FIRST pre-config
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder * hook; it is cleaned up when the associated pool goes away; assume
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder * pconf is the pool passed to ap_mutex_register()
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maederstatic apr_status_t cleanup_mx_hash(void *dummy)
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder apr_pool_cleanup_register(p, NULL, cleanup_mx_hash, apr_pool_cleanup_null);
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder /* initialize default mutex configuration */
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian Maeder apr_hash_set(mxcfg_by_type, "default", APR_HASH_KEY_STRING, def);
0a8ea95bcf0e3f84fed0b725c049ec2a956a4a28Christian MaederAP_DECLARE_NONSTD(const char *)ap_set_mutex(cmd_parms *cmd, void *dummy,
7a879b08ae0ca30006f9be887a73212b07f10204Christian Maeder const char **elt;
7a879b08ae0ca30006f9be887a73212b07f10204Christian Maeder const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
967e5f3c25249c779575864692935627004d3f9eChristian Maeder mechdir = ap_getword_conf(cmd->pool, &arg);
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder return "Mutex requires at least a mechanism argument ("
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder rv = ap_parse_mutex(mechdir, p, &mech, &mutexdir);
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder return apr_pstrcat(p, "Invalid Mutex argument ", mechdir,
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder " (" AP_ALL_AVAILABLE_MUTEXES_STRING ")", NULL);
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder || (mutexdir && !ap_is_directory(p, mutexdir))) {
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder return apr_pstrcat(p, "Invalid Mutex directory in argument ",
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder /* "OmitPID" can appear at the end of the list, so build a list of
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder * mutex type names while looking for "OmitPID" (anywhere) or the end
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder type_list = apr_array_make(cmd->pool, 4, sizeof(char *));
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder char *s = ap_getword_conf(cmd->pool, &arg);
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder char **new_type = (char **)apr_array_push(type_list);
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder if (apr_is_empty_array(type_list)) { /* no mutex type? assume "default" */
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder char **new_type = (char **)apr_array_push(type_list);
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder while ((elt = (const char **)apr_array_pop(type_list)) != NULL) {
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder mxcfg = apr_hash_get(mxcfg_by_type, type, APR_HASH_KEY_STRING);
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder return apr_psprintf(p, "Mutex type %s is not valid", type);
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder mxcfg->none = 0; /* in case that was the default */
83814002b4922114cbe7e9ba728472a0bf44aac5Christian Maeder if (!(mxcfg->options & AP_MUTEX_ALLOW_NONE)) {
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder "None is not allowed for mutex type %s",
dedabc954aa15f6ad0764472a9434dc6dafe3db2Christian Maeder if (mutexdir) { /* retain mutex default if not configured */
const char *type,
const char *default_dir,
return APR_EINVAL;
return APR_SUCCESS;
const char *type,
const char *instance_id)
return NULL;
#if HAVE_UNISTD_H
return ap_server_root_relative(p,
apr_pstrcat(p,
type,
NULL));
if (!mxcfg) {
return NULL;
return newcfg;
type);
const char *fname)
type);
const char *type,
const char *instance_id,
const char *fname;
if (options) {
return APR_EINVAL;
if (!mxcfg) {
return APR_EINVAL;
return APR_SUCCESS;
return rv;
#ifdef AP_NEED_SET_MUTEX_PERMS
return rv;
return APR_SUCCESS;
const char *type,
const char *instance_id,
const char *fname;
if (options) {
return APR_EINVAL;
if (!mxcfg) {
return APR_EINVAL;
return APR_SUCCESS;
return rv;
#ifdef AP_NEED_SET_MUTEX_PERMS
return rv;
return APR_SUCCESS;